{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import math, numpy as np, tensorflow as tf, matplotlib.pyplot as plt, operator\n",
    "from importlib import reload"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Clustering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Clustering techniques are unsupervised learning algorithms that try to group unlabelled data into \"clusters\", using the (typically spatial) structure of the data itself."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "import kmeans; reload(kmeans)\n",
    "from kmeans import Kmeans"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "The easiest way to demonstrate how clustering works is to simply generate some data and show them in action."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Create data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "n_clusters=6\n",
    "n_samples =250"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "To generate our data, we're going to pick 6 random points, which we'll call centroids, and for each point we're going to generate 250 random points about it.\n",
    "\n",
    "In statistical parlance, we're going to simulate 1500 realizations from 6 different bivariate normal distributions (250 each) with random centroids over the range -35, 35."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "centroids = np.random.uniform(-35, 35, (n_clusters, 2))\n",
    "slices = [np.random.multivariate_normal(centroids[i], np.diag([5., 5.]), n_samples)\n",
    "           for i in range(n_clusters)]\n",
    "data = np.concatenate(slices).astype(np.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Below we can see each centroid marked w/ X, and the coloring associated to each respective cluster."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1dbc224518>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids, data, n_samples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "heading_collapsed": true
   },
   "source": [
    "## K means"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "The goal of clustering is to identify these clusters, defined by their centroids, given the raw data with no labels. Once these centroids have been identified, each point is labelled as belonging to the centroid it is closest to.\n",
    "\n",
    "K means clustering is a simple and popular approach of finding appropriate centroids. It does this by taking random centroids, and iteratively moving them to make the clusters as compact as possible.\n",
    "\n",
    "The algorithm is very simple:\n",
    "- Select the number of clusters N you want to find\n",
    "- Guess N random centroids (more on this below)\n",
    "- While centroids change:\n",
    "    - Create clusters by assigning each point to the nearest centroid\n",
    "    - For each cluster, define the new centroid as the centroid of all points assigned to it\n",
    "    \n",
    "Typically the algorithm is terminated once the change in centroids is negligible or after a certain number of iterations.\n",
    "\n",
    "While guessing random centroids is fine in theory, most implementations use the data itself to identify initial cluster points. This speeds up convergence by initializing centroids in the appropriate regime. Typically, inital points are selected amongst the data and tries to pick them to be as far apart as possible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "k = Kmeans(data, n_clusters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "sess = tf.InteractiveSession()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "tf.global_variables_initializer().run()\n",
    "initial_centroids = k.find_initial_centroids(n_clusters).eval()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "Inital \"random\" guesses, based on the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n/g8qGSk1o0ZSHgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1d5c36f048>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(initial_centroids, data, n_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "curr_centroids = tf.Variable(initial_centroids)\n",
    "nearest_indices = k.assign_to_nearest(curr_centroids)\n",
    "updated_centroids = k.update_centroids(nearest_indices)\n",
    "tf.global_variables_initializer().run()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "Updated centroids after one iteration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n/wF6qmnk4oDwOAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1d5803fcc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(updated_centroids.eval(), data, n_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'Assign:0' shape=(6, 2) dtype=float32_ref>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "curr_centroids.assign(updated_centroids)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "with tf.Session().as_default(): new_centroids = k.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1ce46ed860>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(new_centroids, data, n_samples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "The result are centroids that have minimized the total distance between all points and their centroids; the centroids are \"optimal\" in this sense.\n",
    "\n",
    "There are some problems with K-means clustering.\n",
    "* Number of clusters needs to be known a priori\n",
    "    * This is an obvious failure of an unsupervised learning algorithm; we want the data to \"speak for itself\"\n",
    "    * Difficult to identify in higher dimensions\n",
    "    \n",
    "* Naive approach only works if the clusters are the same shape\n",
    "    * This is because centroid is identified using euclidean distance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Mean shift"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Mean shift clustering is a newer and less well-known approach.\n",
    "\n",
    "The algorithm is as follows:\n",
    "* Take each data point X\n",
    "* For each x in X, find the distance between point x and every other point in X\n",
    "* Create weights for each point in X by using the Gaussian function of that point's distance to x\n",
    "    * Gaussian function here is the density function of a Normal distribution of distances with mean 0\n",
    "    * This weighting approach penalizes points further away from x\n",
    "    * The rate at which the weights fall to zero is determined by the bandwidth, which is the standard deviation of the Gaussian\n",
    "* Update x as the weighted average of all other points in X, defined by the weights determined in the previous step\n",
    "\n",
    "This will iteratively push points that are close together even closer until they are next to each other."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def gaussian(d, bw):\n",
    "    return np.exp(-0.5*((d/bw))**2) / (bw*math.sqrt(2*math.pi))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "In our implementation, we choose the bandwidth to be 2.5. \n",
    "\n",
    "One easy way to choose bandwidth is to find which bandwidth covers one third of the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def meanshift(data):\n",
    "    X = np.copy(data)\n",
    "    for it in range(5):\n",
    "        for i, x in enumerate(X):\n",
    "            dist = np.sqrt(((x-X)**2).sum(1))\n",
    "            weight = gaussian(dist, 2.5)\n",
    "            X[i] = (np.expand_dims(weight,1)*X).sum(0) / weight.sum()\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 824 ms, sys: 20 ms, total: 844 ms\n",
      "Wall time: 792 ms\n"
     ]
    }
   ],
   "source": [
    "%time X=meanshift(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We can see that mean shift clustering has almost reproduced our original clustering. The one exception are the very close clusters, but if we really wanted to differentiate them we could lower the bandwidth.\n",
    "\n",
    "What is impressive is that this algorithm nearly reproduced the original clusters without telling it how many clusters there should be."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAD8CAYAAAB0IB+mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFLlJREFUeJzt3WFoZed95/HvP3bq3Ul3kSMPjq/trAwdFZwgEiwMpW+k\n2llP8dBRs7Q4lMVxg0RKEmb9oqldQ+8VxWAw1C+2SUFiMzXU1Bh2Ox5m0iZOViIUNnXkJqv1ONb1\n0EywIzvW3CCyYSDF9r8vdK/makYzmvG9V1dzn+8HLvec5zk65zlnxG+OnvOccyIzkSQNvg/0uwGS\npN1h4EtSIQx8SSqEgS9JhTDwJakQBr4kFcLAl6RCdBz4EfHvIuLFiPi/EXEqImab5R+OiBci4rXm\n942dN1eS9H5FpzdeRUQAH8rMX0TEB4F/BI4AnwZ+lplPRMQjwI2Z+Scdt1iS9L5c3+kKcuN/jF80\nZz/Y/CRwGJholj8NLAKXDfybbropR0ZGOm2SJBXlpZdeOpuZ+3daruPAB4iI64CXgF8DvpKZ/xQR\nN2fmm81F3gJu3mk9IyMjLC0tdaNJklSMiPjxlSzXlYu2mfluZn4CuA24OyI+fkF9snHWf5GImImI\npYhYWltb60ZzJEnb6OooncxcBxaAg8BPI+IWgOb325f4mbnMHM/M8f37d/yLRJIGRqPRuKryTnVj\nlM7+iBhqTv974FPAq8Bx4MHmYg8Cz3e6LUkaFLVajbGxMer1+pbyer3O2NgYtVqt69vsxhn+LcBC\nRCwD3wNeyMwTwBPApyLiNeDe5rwkFa9WqzE7O8vq6iqTk5OboV+v15mcnGR1dZXZ2dmuh343Ruks\nA5/cprwB3NPp+iVpkLTCvqUV+nNzc8zMzLC6urpZ11quW8HvnbaStEsajQbz8/NbyqaY4tzqOQ4d\nOsS51XNMMbWlfn5+vmt9+ga+irHbF8ikCw0PD7OwsEClUgE2wv4IR3iKpxhhhKd4iiMc2Qz9SqXC\nwsICw8PDXdm+ga8i9OMCmbSd0dHRzdBfZJEznGGEEY5ylBFGOMMZFlncDPvR0dGubdvA18Dr1wUy\n6VJGR0eZm5tjnXVmmd1SN8ss66wzNzfX1bAHA18D7lIXyE6ePLkZ9i2GvnZLvV5nZmaGIYaoUt1S\nV6XKEEPMzMxc9Bdppwx8Dax+XyCTttP+l+UEE5vdOA/x0Gb3zgQTF/1F2hWZuWc+d911V0rdtLKy\nkpVKJYGcYioXWMijHM0RRvIoR3OBhZxiKoGsVCq5srLS7yZrgJ09e3bz97H1mWIqhxhKIIcY2vx9\nbH0qlUqePXv2susFlvIKMtYzfA20fl4gky40PDzM9PT0lrJjHGNfZR8nTpxgX2Ufxzi2pX56etpR\nOtKV6tcFMmk7tVqNavV8v33rZOP+++/fMmQToFqtdvW6UscvQOmm8fHx9PHI6rZWn+m51XOb451b\nznCGh3mYfZV9nuGrI7Nxfrp6BbFaq9WYn5+/6Peu9fs6PT19xWEfES9l5vhOy3mGr4HW1wtk0mXU\najWWl5cvOskYHR1leXm5JyPGuvICFGkvajQaW4ZetvpGF1lknXUe5mEmmNgsb4X+8vJy1/pMpcu5\n1O9Zr37/PMPXwOr3BTKVpZrnP3uVga+B1s8LZNJeY5eOBl4rxC+8QNYasnm1F8ika5WjdPawRqOx\nbffCpcqL9Vdtd8v+0bFLLubx1KBylM41zqc7dt9uXyCT9hoDfw/y6Y6SesE+/D2mn68/u2ZdphtH\n0nme4e8hPt1RUi8Z+HtIv19/JmmwGfh7jE93lNQrBv4e5NMdJfWCgb8H9ev1Z5IGW8eBHxG3R8RC\nRLwSEaci4kiz/MMR8UJEvNb8vrHz5g4+n+4oqVc6vtM2Im4BbsnMf46I/wC8BEwBnwV+lplPRMQj\nwI2Z+SeXW1fpd9o2Gg3Gxsa2DL2cYmrz6Y5DDG15uiNsXLj16Y5S2XbtTtvMfDMz/7k5/f+BHwK3\nAoeBp5uLPQ0XjCfURXy6o6Re6uqNVxExAnwS+Cfg5sx8s1n1FnDzJX5mBpgB+OhHP9rN5uxJJ37x\nV5vTh371jy6qb91E1bqpqn00TutBX62/AHy6o6Sr0bXAj4hfBf4n8N8y8+cR59/3lZkZEdv2HWXm\nHDAHG1063WrPtcynO0rqha4EfkR8kI2wfyYz/1ez+KcRcUtmvtns53+7G9sqRa1W40tf+tJF3TWt\n15/ZjSPpanUc+LFxKv8/gB9m5l+0VR0HHgSeaH4/3+m2BsF23TiX4tMdJXVTN87wfxP4r8D/i4gf\nNMv+lI2gfy4iPgf8GPj9LmxLkvQ+dRz4mfmPQFyi+p5O1y9J6g7vtJWkQhj4klQIA1+SCmHgS1Ih\nDHxJKoSBL0mFMPAlqRAGviQVwsCXpEIY+JJUCANfkgph4EtSIQx8SSqEgS9JhTDwJakQBr4kFcLA\nl6RCGPiSVAgDX5IKYeBLUiEMfEkqhIEvSYUw8CWpEF0J/Ij4WkS8HREvt5V9OCJeiIjXmt83dmNb\nkqT3p1tn+H8NHLyg7BHg25l5APh2c16S1CddCfzM/A7wswuKDwNPN6efBqa6sS1J0vvTyz78mzPz\nzeb0W8DNPdyWJGkHu3LRNjMTyO3qImImIpYiYmltbW03miNJRepl4P80Im4BaH6/vd1CmTmXmeOZ\nOb5///4eNkeSytbLwD8OPNicfhB4vofbkiTtoFvDMv8W+D/Ar0fEGxHxOeAJ4FMR8Rpwb3NektQn\n13djJZn5mUtU3dON9UuSOuedtpJUCANfkgph4EtSIQx8SSqEgS9JhTDwJakQBr4kFcLAl6RCGPiS\nVAgDX5IKYeBLUiEMfEkqhIEvSYUw8CWpEAa+JBXCwJekQhj4klQIA1+SCmHgS1IhDHxJKoSBL0mF\nMPAlqRAGviQVoueBHxEHI2IlIk5HxCO93p4kaXs9DfyIuA74CvDbwJ3AZyLizl5uU5K0vV6f4d8N\nnM7Mf8nMfwWeBQ73eJuSpG30OvBvBV5vm3+jWSZJ2mV9v2gbETMRsRQRS2tra/1ujiQNrF4H/k+A\n29vmb2uWbcrMucwcz8zx/fv397g5klSuXgf+94ADEXFHRPwK8ABwvMfblCRt4/perjwz34mILwLf\nAK4DvpaZp3q5TUnS9noa+ACZ+XXg673ejiTp8vp+0VaStDsMfEkqhIEvSYUoNvAbjcZVlUvSta7I\nwK/VaoyNjVGv17eU1+t1xsbGqNVq/WmYJPVQcYFfq9WYnZ1ldXWVycnJzdCv1+tMTk6yurrK7Oys\noS9p4BQV+K2wb2mF/smTJzfDvsXQlzRoign8RqPB/Pz8lrIppji3eo5Dhw5xbvUcU0xtqZ+fn7dP\nX9LAKCbwh4eHWVhYoFKpABthf4QjPMVTjDDCUzzFEY5shn6lUmFhYYHh4eF+NluSuqaYwAcYHR3d\nDP1FFjnDGUYY4ShHGWGEM5xhkcXNsB8dHe13kyWpa4oKfNgI/bm5OdZZZ5bZLXWzzLLOOnNzc4a9\npIFTXODX63VmZmYYYogq1S11VaoMMcTMzMxFQzYl6VpXVOC3D72cYGKzG+chHtrs3plg4qIhm5I0\nCCIz+92GTePj47m0tNSTdTcaDcbGxrYMvZxiikUWWWedIYaYYIJjHNusr1QqLC8ve+FW0p4WES9l\n5vhOyxVzhj88PMz09PSWsmMcY19lHydOnGBfZd+WsAeYnp427CUNjGICHzZuvKpWz/fbt0bj3H//\n/VuGbAJUq1VvvJI0UHr+ApS9phXi8/PzW4ZetoZsTk5OMj09bdhLGjjF9OFfqNFobNtdc6lySdqr\n7MPfwaVC3bCXNKiKDXxJKo2BL0mFKDLwfduVpBIVF/i+7UpSqToK/Ij4vYg4FRHvRcT4BXWPRsTp\niFiJiPs6a2Z3+LYrSSXr9Az/ZeDTwHfaCyPiTuAB4GPAQeCrEXFdh9vqiG+7klS6jgI/M3+YmSvb\nVB0Gns3MX2bmj4DTwN2dbGsnv/XW9zn08+/zW299/6I633YlSb3rw78VeL1t/o1mWc/s2wcf+MDG\n94V825UkXUHgR8S3IuLlbT6Hu9GAiJiJiKWIWFpbW3vf6zl3Dt57b+N7O77tSlLpdnyWTmbe+z7W\n+xPg9rb525pl261/DpiDjUcrvI9tAfC/P/LJjYn/eOllWm+7OnToELPMcpSjm3Wtt139zdzfGPaS\nBlKvunSOAw9ExA0RcQdwAHixR9u6Yr7tSlLJOh2W+bsR8QbwG8DJiPgGQGaeAp4DXgH+AfhCZr7b\naWM74duuJJWuiKdl+rYrSYPMp2W28W1XklRI4INvu5Kkot545duuJJWsiD78C/m2K0mDxD78y/Bt\nV5JKVGTgS1KJDHxJKoSBL0mFMPAlqRAGviQVwsCXpEIY+JJUCANfkgph4EtSIQx8SSqEgS9JhTDw\nJakQBr4kFcLAl6RCGPiSVAgDX5IKYeBLUiEMfEkqhIEvSYXoKPAj4smIeDUiliPi7yJiqK3u0Yg4\nHRErEXFf502VJHWi0zP8F4CPZ+YYUAceBYiIO4EHgI8BB4GvRsR1HW5LktSBjgI/M7+Zme80Z78L\n3NacPgw8m5m/zMwfAaeBuzvZliSpM93sw/9D4O+b07cCr7fVvdEsu0hEzETEUkQsra2tdbE5kqR2\n1++0QER8C/jINlWPZebzzWUeA94BnrnaBmTmHDAHMD4+nlf785KkK7Nj4GfmvZerj4jPAoeAezKz\nFdg/AW5vW+y2ZpkkqU86HaVzEPgy8DuZea6t6jjwQETcEBF3AAeAFzvZliSpMzue4e/gL4EbgBci\nAuC7mfn5zDwVEc8Br7DR1fOFzHy3w21JkjrQUeBn5q9dpu5x4PFO1i9J6h7vtJWkQhj4klQIA1+S\nCmHgS1IhDHxJKoSBL0mFMPAlqRAGviQVwsCXpEIY+JJUCANfkgph4EtSIQx8SSqEgS9JhTDwJakQ\nBr4kFcLAl6RCGPiSVAgDX5IKYeBLUiEMfEkqhIEvSYUw8CWpEB0FfkT8eUQsR8QPIuKbEVFpq3s0\nIk5HxEpE3Nd5UyVJnej0DP/JzBzLzE8AJ4A/A4iIO4EHgI8BB4GvRsR1HW5LktSBjgI/M3/eNvsh\nIJvTh4FnM/OXmfkj4DRwdyfbkiR1puM+/Ih4PCJeB/6A5hk+cCvwettibzTL1KFGo3FV5ZLUsmPg\nR8S3IuLlbT6HATLzscy8HXgG+OLVNiAiZiJiKSKW1tbWrn4PClKr1RgbG6Ner28pr9frjI2NUavV\n+tMwSdeGzOzKB/go8HJz+lHg0ba6bwC/sdM67rrrrtT2qtVqstFllpVKJVdWVjIzc2VlJSuVymZd\ntVrtb0Ml7TpgKa8gpzsdpXOgbfYw8Gpz+jjwQETcEBF3AAeAFzvZVslqtRqzs7Ob86urq0xOTnLy\n5EkmJydZXV3drJudnfVMX9K2Ou3Df6LZvbMM/GfgCEBmngKeA14B/gH4Qma+2+G2itRoNJifn99S\nNsUU51bPcejQIc6tnmOKqS318/Pz9ulLusj1nfxwZv6Xy9Q9DjzeyfoFw8PDLCwsbJ7JTzHFEY5w\nmMPMMkuVKiOMAHCMY1QqFRYWFhgeHu5vwyXtOd5pew0YHR1lYWGBSqXCIouc4QwjjHCUo4wwwhnO\nsMjiZtiPjo72u8mS9iAD/xoxOjrK3Nwc66wzy+yWullmWWedubk5w17SJRn4e8nZs/DkkxvfF6jX\n68zMzDDEEFWqW+qqVBliiJmZmYuGbEpSi4G/lxw9Cl/+8sZ3m3q9vtmHP8HEZjfOQzy02b0zwcTm\n6B1DX9J2Orpoqy576KGt32yM0mkfenmMYwAsssg66zzMw0wwsVneCv3l5WUv3ErawjP8veSmm+CP\n/3jju2l4eJjp6ektix3jGPsq+zhx4gT7Kvs2w75lenrasJd0EQN/L4k4/2lTq9WoVs/327dG49x/\n//2bo3daqtWqN15J2pZdOteIVojPz89vGXrZGrI5OTnJ9PS0YS/pkmLjMQx7w/j4eC4tLfW7Gf3T\nfmZ/iX+XRqOxbXfNpcolDb6IeCkzx3dazjP8veQK/vO9VKgb9pJ2Yh++JBXCwJekQhj4klQIA1+S\nCmHgS1IhDHxJKoSBL0mF2FM3XkXEGvDjXdrcTcDFzyEui8fAYwAeg0HY//+Umft3WmhPBf5uioil\nK7kzbZB5DDwG4DEoaf/t0pGkQhj4klSIkgN/rt8N2AM8Bh4D8BgUs//F9uFLUmlKPsOXpKIUF/gR\n8ecRsRwRP4iIb0ZEpa3u0Yg4HRErEXFfP9vZKxHxZES82jwGfxcRQ211A7//ABHxexFxKiLei4jx\nC+qKOAYAEXGwuZ+nI+KRfrdnN0TE1yLi7Yh4ua3swxHxQkS81vy+sZ9t7KXiAh94MjPHMvMTwAng\nzwAi4k7gAeBjwEHgqxFxXf+a2TMvAB/PzDGgDjwKRe0/wMvAp4HvtBeWdAya+/UV4LeBO4HPNPd/\n0P01G/+27R4Bvp2ZB4BvN+cHUnGBn5k/b5v9ENC6iHEYeDYzf5mZPwJOA3fvdvt6LTO/mZnvNGe/\nC9zWnC5i/wEy84eZubJNVTHHgI39Op2Z/5KZ/wo8y8b+D7TM/A7wswuKDwNPN6efBqZ2tVG7qLjA\nB4iIxyPideAPaJ7hA7cCr7ct9kazbJD9IfD3zekS9/9CJR2DkvZ1Jzdn5pvN6beAm/vZmF4ayFcc\nRsS3gI9sU/VYZj6fmY8Bj0XEo8AXgequNrDHdtr/5jKPAe8Az+xm23bLlRwD6UKZmRExsEMXBzLw\nM/PeK1z0GeDrbAT+T4Db2+pua5Zdc3ba/4j4LHAIuCfPj8sdmP2Hq/odaDdQx2AHJe3rTn4aEbdk\n5psRcQvwdr8b1CvFdelExIG22cPAq83p48ADEXFDRNwBHABe3O329VpEHAS+DPxOZp5rqypi/3dQ\n0jH4HnAgIu6IiF9h42L18T63qV+OAw82px8EBvYvwIE8w9/BExHx68B7bDyZ8/MAmXkqIp4DXmGj\nq+MLmflu/5rZM38J3AC8EBEA383Mzxe0/0TE7wL/HdgPnIyIH2TmfSUdg8x8JyK+CHwDuA74Wmae\n6nOzei4i/haYAG6KiDfY+Ov+CeC5iPgcG5nw+/1rYW95p60kFaK4Lh1JKpWBL0mFMPAlqRAGviQV\nwsCXpEIY+JJUCANfkgph4EtSIf4NdvQQawIGDIwAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1ce4654a20>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids+2, X, n_samples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We should be able to accelerate this algorithm with a GPU."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## PyTorch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "GPU-accelerated mean shift implementation in pytorch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "import torch_utils; reload(torch_utils)\n",
    "from torch_utils import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "The advantage of pytorch is that it's very similar to numpy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def gaussian(d, bw):\n",
    "    return torch.exp(-0.5*((d/bw))**2) / (bw*math.sqrt(2*math.pi))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Torch does not support broadcasting, therefore Jeremy has replaced the distance subtraction line with a subtraction function from his custom pytorch broadcasting library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def meanshift(data):\n",
    "    X = torch.FloatTensor(np.copy(data))\n",
    "    for it in range(5):\n",
    "        for i, x in enumerate(X):\n",
    "            dist = torch.sqrt((sub(x, X)**2).sum(1))\n",
    "            weight = gaussian(dist, 3)\n",
    "            num = mul(weight, X).sum(0)\n",
    "            X[i] = num / weight.sum()\n",
    "    return X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "This implementation actually takes longer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 2.02 s, sys: 0 ns, total: 2.02 s\n",
      "Wall time: 1.9 s\n"
     ]
    }
   ],
   "source": [
    "%time X = meanshift(data).numpy()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "All the computation is happening in the <tt>for</tt> loop, which isn't accelerated by pytorch.\n",
    "\n",
    "Each iteration launches a new cuda kernel, which takes time and slows the algorithm down as a whole."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nC5d2XTfJAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1c24e81d30>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids+2, X, n_samples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "### GPU"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "To truly accelerate the algorithm, we need to be performing updates on a batch of points per iteration, instead of just one as we were doing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def dist_b(a,b):\n",
    "    return torch.sqrt((sub(a.unsqueeze(0),b.unsqueeze(1))**2).sum(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       " 0.2547  0.7809  0.4620\n",
       " 0.3356  0.8589  0.4897\n",
       "[torch.FloatTensor of size 2x3]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=torch.rand(2,2)\n",
    "b=torch.rand(3,2)\n",
    "dist_b(b, a).squeeze(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def gaussian(d, bw):\n",
    "    return torch.exp(-0.5*((d/bw))**2) / (bw*math.sqrt(2*math.pi))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def sum_sqz(a,axis): return a.sum(axis).squeeze(axis)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def meanshift(data, bs=500):\n",
    "    n = len(data)\n",
    "    X = torch.FloatTensor(np.copy(data)).cuda()\n",
    "    for it in range(5):\n",
    "        for i in range(0,n,bs):\n",
    "            s = slice(i,min(n,i+bs))\n",
    "            weight = gaussian(dist_b(X, X[s]), 2)\n",
    "            num = sum_sqz(mul(weight, X), 1)\n",
    "            X[s] = div(num, sum_sqz(weight, 1))\n",
    "    return X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Although each iteration still has to launch a new cuda kernel, there are now fewer iterations, and the acceleration from updating a batch of points more than makes up for it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 48 ms, sys: 36 ms, total: 84 ms\n",
      "Wall time: 78.9 ms\n"
     ]
    }
   ],
   "source": [
    "%time X = meanshift(data).cpu().numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1c24d57358>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids+2, X, n_samples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## LSH"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "TO-DO: Needs notes?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "from sklearn.neighbors import LSHForest, KDTree, BallTree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "n_clusters=6\n",
    "n_samples =2500"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "centroids = np.random.uniform(-35, 35, (n_clusters, 2))\n",
    "slices = [np.random.multivariate_normal(centroids[i], np.diag([5., 5.]), n_samples)\n",
    "           for i in range(n_clusters)]\n",
    "data = np.concatenate(slices).astype(np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[   0, 1918,  905],\n",
       "       [   1,  102, 1294],\n",
       "       [   2, 2345, 1397],\n",
       "       [   3, 2383,  943],\n",
       "       [   4,   15, 1886],\n",
       "       [   5, 2243,  161],\n",
       "       [   6, 2085, 1853],\n",
       "       [   7, 2222, 2177],\n",
       "       [   8,  324, 2008],\n",
       "       [   9,  396, 1659]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nn = KDTree(data)\n",
    "nearest = nn.query(data[:10], 3, False); nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[   0, 1918,  905],\n",
       "       [   1,  102, 1294],\n",
       "       [   2, 2345, 1397],\n",
       "       [   3, 2383,  943],\n",
       "       [   4,   15, 1886],\n",
       "       [   5, 2243,  161],\n",
       "       [   6, 2085, 1853],\n",
       "       [   7, 2222, 2177],\n",
       "       [   8,  324, 2008],\n",
       "       [   9,  396, 1659]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nn = BallTree(data)\n",
    "nearest = nn.query(data[:10], 3, False); nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAD8CAYAAAB0IB+mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvXt8VdWZ//9e55aTe0ISQgiEoAGiQJGCivqlouClQhWc\nab3Md6q0U2faWm+ddtReIrW1/dYZtdbRGfptxfn1a9V5VagD1ioqrTeEUERBQBACJISQhNyTc9ln\nr98fa+999jm5X7hmvV8vXvvstffZlwN81rOe51nPElJKNBqNRnPm4znZD6DRaDSaE4MWfI1Goxkl\naMHXaDSaUYIWfI1GoxklaMHXaDSaUYIWfI1GoxklaMHXaDSaUYIWfI1GoxklaMHXaDSaUYLvZD+A\nm/z8fFlaWnqyH0Oj0WhOK7Zs2dIgpSzo77xTSvBLS0uprKw82Y+h0Wg0pxVCiAMDOU+7dDQajWaU\noAVfo9FoRgla8DUajWaUoAVfo9FoRgla8DUajWaUoAVfo9FoRgkjJvhCCK8QYqsQYq21P0YI8ZoQ\nYo+1zR2pe2k0Go1m8IykhX8nsNO1fy/wupRyCvC6ta/RaDSak8SICL4QYgKwGPi/rubrgGesz88A\nS0fiXhrNySYiu/g0spWI7Dotr68ZvYyUhf8Y8F3AdLUVSilrrc9HgMKeviiEuE0IUSmEqKyvrx+h\nx9Fojh+HorvYGdnIoeiuQX1voEI+1OtrNP0xbMEXQiwBjkopt/R2jpRSArKXYyullHOllHMLCvot\nBaHRnFB6EumJ/nLOCcxjor+813N6ahuokBf6ShnrLaHQVzqyL6MZ9YyEhX8JcK0Qogp4DrhcCPFb\noE4IUQRgbY+OwL00mgSOt/ujJ5EOiFTODswmIFITzvkg9IbzHPsj29kZ2cj+yHbnewMV8jqjiqOx\ng9QZVSP+PprRzbAFX0p5n5RygpSyFLgReENK+b+Bl4BbrNNuAf4w3HtpNMkcb/fHRH85U/xzMKTh\niHlyJ1PoKyVd5HA0dtD1HGpAG5NR59yBCnnyCEKjGSmOZ7XMnwEvCCG+ChwAvnQc76UZpdiiOBBx\njMguDkV3MdFf7ljn/REQqfiEn52RjfiEj7MDs51OxpAGAE2xWjpkM/meCRgySkR2MTkwE5/wEza7\n2BnZSNjswiv8TPHPYaK/POFZgITnskcQGs1IM6KCL6XcAGywPjcCC0fy+hpNMoMRR1uoAec7PQlv\noa+UOqPKEeDkTsXeGjLKnqgKXaWRRbrIdvanpVzA2YHZ7A5vBqDVbKTBrOacwDwAPgi9wdHYQQ5G\nd1Hom8S+6DYaY4c5L3h5QmfUWyfVV4eh0fTGKVUPX6M5nrgF2xZMQxrsiao1GOzP9UY1DWZ1ggBP\n9JezN7yVVrOBGcH5nB2YTUR20RSro8GsppNW6s1qAOqNauqNajwIyoMXAZKYNMjy5mHIKPsj2zka\nO4gHHx2ymdZYOmO9JRyNHeSvXevJ9RYyOTATgL92vUaDWYMho0xLucB5l/2Rj9gT3YIhowDOZ/c5\nGk0yWvA1ZxR9uW3co4FPI1vZGdnIWb5ZjPWWkOst4pPwJkBZ7mlkOT55242zz9gGwPbQ28xL+wIR\nGcKUBpnk0UUrnbIFHyk0yzrnnpu6XsaHjxAdjBHjOCaPkEU+flKIEiZd5DA15QKORPfRLlpoMFVn\n02LWk+0poMGssa4kkt5U7TfF6sjy5vVyjkaTiBZ8zRlFT26bnrCt/bDZxdHYQcxwjAazBg8+R7DT\nRBZhs4uI7GKiv5yayKe0Uk/I7GR3eDP1xqEEcQcwCOPBj0kUgcAgjEEYgE7ZBkArDQB48ZPvKeaT\n8CZH2HNEIRHUM2V7xjLFPwcQTA7MSLjP5MAMWsyjHI0dJNdbqIO8mgGhBV9zRjGYIC7gGMUBkYrA\ng4mBFz8mMTplK/uMbdQa+yjynYVP+EBCO8fYEz2GF3+PlzSJ4iMFgzACDxITj2Xlu4kR5UBsB4Bj\n8YfppEu2ke8ppthfRp1RRaGvtNuoJSBSOS94uZX2KbX/XjMgdLVMzaij3Wzi7c7VaiQg4ZzAPJpj\nR5GYCDzEiCJdk8a7aGOfsY0IIQRepz1GtNd72Fa9fR0To9dzA6QSJUxQZNBljQKyPPnUGVXsjGzk\n4/C7PaaeqgwiH3uiW5xjuiyDpi+0ha85LRhoSmVfLp1jsSNsC72JX6TQKVsA8AqfsqAje/DgZar/\nAmqNvbTJJiQSScz5frtsOg5vBhGUOJsyhpcAMSLEMMj1FpEuchjrLaXdbKYt1sTu8CaK/VOoie4F\nJMX+KQAJ2ToDcWlpRida8DWnBf0Jmd0h2LNY3WUP9kc+AgQ1xid0yla80k9QZBCUaRT4Sni/cx1d\nKMv6QPQjumg/Ie+UTAzDGTU0xg5z0NiJxGRX5H0MwnTGWiEGLWY9R2MHne+5M3MG7dLSjCq04GtO\nC/oTst46hEPRXU5u/ATPNCJSBVFjMkqIdraF3nTEHiBiuWKGQmtjO1l5GQNuT8btInKPJvK846mL\n7SdbFODFS4BUUkWm5f5JzMzRk7Y0faF9+JrTguT6Ncn0Vo5gor+cMWIcoNw3fgLqeqThI0CHbE44\nX4nu4NMbn31oLd+66CfU7EnM2qnZU8e3LvoJzz60tt9rZPSyRlBXrJ18zwS8eDkmj1Ad202XbGOs\nt4Rif5njs0/232t/viYZbeFrzgj6tGyFAAktZoNjzceI9hF07bGwa688+9BafvfTlwG4f/FjPLTu\nLoqnFFKzp477Fz/GsdoW5/jN9y/p9Tq9xQg6aKbVVM8aJJ0AaXg8HjJELjXRPc4IBnDKOLTLJjJE\nrjN3QFv9GtCCrznDcPvya6J7aYrVcsxUyzK4Bb6vDJvB4BZ7gGO1Ldy/+DFuf/xmnrjjWY7VtjjH\nBiL6PeF+1hAdKr3ThGazjin+ud1GNvXGIRrMGkxPTOfnaxLQLh3NaUlv7grbl/9x+F32RCtpMGtI\nIwuAqOzLPy8YrCuntbGdP616J6FtKUsxawU/+uJTmLWCpUkLvf1p1Tu0Ng41KKyeb4wYxyTfdMaI\nccSIdiu6NjkwCx8pBD2ZOj9fk4C28DWnJb0FaW1rttBXSnZ0LHbqYp1RRafZxgFjRy9XHJwbByAr\nL4OH1t3luG2WspQ7uZPruI4VrKCCCkopBWANaxhTlM1D6+4aUAC392cUpHmyATgmj3AsegSAc1Mu\ndkY39cYhDMJUG7uIyM5uBdk0oxehFqM6NZg7d66srKw82Y+hOQ0YSBXJZJGLyC4qu/7EMbMWD75u\nk6FSyUzI2Bkotq/erBU8yqOOyANUUcXd3I2nSDq+/cHgwYvpzAUQ2B2TFx8x6/lTyWCCvxyQ7Ilu\nIYdCwnSQItJplnWM9Zb0KPpDKRetOTURQmyRUs7t7zzt0tGcFIabQdJb1k5PC6K0m01s6lpHRIaY\nm3oV5wTmkYE7I0aQRQHTUi4c0rMUTynk9sdvpplmVrAi4dgKVtBMM7c/fvOgxR5UyQWAVJFJuX8e\nwnLrxJzOStBFu1XxUzDWW0IzdXTRToFvolOFs6cFYvTauaMPLfiak8LxEpue0jM/Dr/L0dhBNne9\nAih3T5SQ61uSVur5ILx+SPes2VPHE3c8Sw45VFCRcKyCCnLI4Yk7nu2WsjkQwnQC0CXb2BPdjOzm\nepLke4qZ4p/L5MAMzk25mHxPMWf5ZzE5MIPzgpf3GrjVK2uNPkZiEfOgEGKTEGKbEGKHEGKF1T5G\nCPGaEGKPte05yVgzKhkJselplGDXrj8U3UW72cSnka2UBeaQLnLokM3sj3zkzKz1OiEsgRjifwV3\n6uUCFlBKKVVUsZzlVFFFKaUsYIGTvTMU0beJuVxQHqumT5rIItdbxOTADAIilTqjigazhhQriOse\nCSX/Xv3NbdCceYxE0DYMXC6lbBdC+IG3hRB/BK4HXpdS/kwIcS9wL/AvI3A/zRnASMwI7Wt27c7I\nRic9Md9TzPmpV1NnVGFIw/HTm06BNNmD5dw/rY3tjtiDCswCbGADzTRzN3ezgAVOuy36v3zve0MK\n3HrxOymaflLwCC8FnonsiVY6yy9O9JdjyKizBq9bzHWdHc1ILGIupZR2npnf+iOB64BnrPZnICk/\nTaMZJn3Nrj0nMI90Tw4ADWYNNdE9ABT7y8gRypfurog5FLLyMrjq1ksS2tawBk+R5If//XU8RdIR\ne5urbr1kSGLvwctYUcJZvlmkkuGUUW6Tx5jkm069cYh2s8lZg3dPtLKbu8z9e+lZuKOTEfHhCyG8\nQogPgKPAa1LK94FCKWWtdcoRYPARK42mD3pzSdjttstmjCgCBDsjG6kzqijwTQQgx1OI1yq1MFRu\nvn8JN913jbNvp16ef/VMHlp3F2OKsp1jN913zaAmXdluJlWnP0at/JRWs4GAJ/6+x8xaGmI1NJg1\nfBx+F+i9I3T/XjpgOzoZkTx8KWUMOE8IkQOsFkLMSDouhRA9jpmFELcBtwGUlJSMxONoNICqnQOQ\n5xvP5MAMfFYp5IORnYzxFIGEGBE8eEkliw6GVv7YFvE/rXonIfWyeEqhk6d/1a2XDHqGrT0C8eAl\nhkkqma4lDxVjPEWUp8xjb2QL56ZcDAzMXaarao5ORjwPXwjxQ6AT+BqwQEpZK4QoAjZIKaf19V2d\nh68ZSXrKM7fXsrXxEyRKiHxPMSamU4YBEnPdB8Jwq2X2Rb5nAjOC/4ua6B5iGDQbdRyTRzjLN4sU\nT6rOpR/lnLA8fCFEgWXZI4RIBa4AdgEvAbdYp90C/GG499JoBkNPLp+J/nKm+OcwyTudMaKIQl8p\nY8Q45e+X8UlNoLJi0oRyyYgBlF3oTdT7E3svfmclLYEg3TVHwH6WZvMoHWYrPuGnLDCbz6QuYKxX\njYi1a0YzUEbCpVMEPCOE8KI6kBeklGuFEO8BLwghvgocAL40AvfSaIZFQKQyLeUCdoc3cyxWyzGj\nlnzPBKfkgo8ABhEAp/58Jy3dsnh6mqk7FATCybzx4ccgmpAiao8wDCJsCb2acM+jsYNk+8fqXHrN\ngBm24EspPwS6OQyllI3AwuFeX6MZCbq7d5SA53uKyfLk0WBWAzhiD9AhWzEIM0aMI8dXSE10L2Fr\nIXIlvPFSB0HSuy1SHiDVWr7QY51pIvAiieEnFR8+J0U031Os7mctzNITJgZjvSUJ4q5dOZrBoIun\naUYFyTnokwMz8Qm/I56tZoMTEM3xFBI2O5ylDjO9eaSIVD4TvJSPQn92rH17FmwOYzk39RL+2vUq\nIToIkIoXH3ne8VTHdgOma3ygPvnwMcE/lYgM0WE2MyM4n4gMsy30JuemXMye8BaaZR0ppJFKBtne\nAgKeVGeClf0eNroujmYgaMHXnFYMVdiSs1KSM1k+m3qFs/bt5MAM9ke2W/VpoD52iE6jlbHeEkJ0\nOPVpbAr8JdQbBx0LX2LSRRudshU/KURdyyamkU2YDvwE2RPdwlhvCQ1mDXVGFWcHZnNZ+k0ANBo1\nNBt1FPumUJYyu993tjs0Q0adjkwLvyYZLfia04qhzhbtL1XR9u3bTA6ozOKmWC0NZg1jvSWcm3Ix\necZ4p/RyTLoWVJHKt24LfLrIIcczlmNmLUHSAUGKSKVF1gPQSj1jPEVkiFwyfLmEZRe7w5uYHJhJ\nQKTiFX51YQEfhN5wOpje3sHuyAxp6Nm0ml7Rgq85rThR+eOqAzi/24giI5BLRHbhEz4mB2Y4HdAU\n/1zH8rfLEQOkeFIxpMGeaCUZIjuh7L4HD/uMbep7hhL0FrOe84KXO/MGDBl1rtnXO9sdmv1sOoir\n6Qkt+JrTipGowTPc+7lHGckdkN05JH+2J33VRPcQMUN0yBamppxPQayWQl8pGdFcjkT3O6WMzw7M\ndgTcDg5HZKhf186J/n00pxda8DWaQeIWebfAuuvSJLue7HOmpVzAp5GtHIjsoCA2wWlPEal00trN\nkle1cXzsjGykxazv17Wj0fSFFnyNZpD0ZkX3Zfm76elYcifS0/mFvlLyjPHaXaMZMnqJQ41mhNCp\nkZqThV7iUKM5wfS3oIguSaw52WjB12hOELokseZko334Gs0JQpck1pxstOBrNCcInTKpOdlol45G\no9GMErTgazQazShBC75Go9GMErTgazQazShhJJY4nCiEeFMI8bEQYocQ4k6rfYwQ4jUhxB5rm9vf\ntTQajUZz/BgJC98Avi2lPBeYB3xTCHEucC/wupRyCvC6ta/RaDSak8SwBV9KWSul/Kv1uQ3YCRQD\n1wHPWKc9Aywd7r00Go1GM3RG1IcvhChFrW/7PlAopay1Dh0BCkfyXhqNRqMZHCMm+EKIDOD3wF1S\nylb3MakqtPVYpU0IcZsQolIIUVlfXz9Sj6PRaDSaJEZE8IUQfpTY/z8p5YtWc50Qosg6XgQc7em7\nUsqVUsq5Usq5BQUFI/E4Go1Go+mBkcjSEcCvgZ1Sykdch14CbrE+3wL8Ybj30mg0Gs3QGYlaOpcA\nfw98JIT4wGq7H/gZ8IIQ4qvAAeBLI3AvjUaj0QyRYQu+lPJt1KKbPbFwuNfXaDQazcigZ9pqNBrN\nKEELvkaj0YwStOBrNBrNKEELvkaj0YwStOBrNBrNKEELvkaj0YwStOCPNA0N8PDDans63u9EP79G\nozlhaMEfaZ5+Gr77XbUdKXoSYbvtiSd6v99QxPt4PL9Gozkl0II/0ixfDj//udr2RbIY9yXqP/+5\nEuEnnogfs4UZer+fW7wHKv4DfX6NRnPaMRKlFTRu8vPhO9/p/7wnnoAVK6CjAx54IFHA7e/bbZde\nqvY7O+PfX75cfdfdlowt2suX93z94Ty/RqM57dAW/smgoQHeeSdxv6NDCW1HR9wKv/ZauOYamDEj\nfq5tpefnQ3q62l+xAm65pftoAeJif+213S13t9Xf0KA6ngce0P57jeYMRVv4J4Onn4b165WY3367\n2l+xQu2//LIS8u98B373O7X/ne8osa6vV1b6gQOwfz/84Afq2OrV6rxbboFHHlHXXL9enb9jhzoG\ncfFfvlx1GG6rH9QzAGzeDM88o84B1QG4v6fRaE5LtOCPJAMRRtuar6hQwpyfr6zvV1+FyZNV+/Ll\nsHs3/Nd/qe+8/TZceWX8Gn/6E+zdq4T5S19Sn8vKlLBv3qyEHuA3v4HGRtWR2L75hx9Wx93Wvr3t\n6FAjj5dfVu+R7FoC7e7RaE5jtEtnuLjdIgPJcLF996DEvqEB7rlHWeT//u9KsCsr4bOfVVY8wHvv\nqe/s3Kms/69/HXJylHA/Yy0b/LnPQXm5aktLg5ISJfZlZTB9uhL4Z59V5779NmzcCPPnw8yZ8ed9\n4AE1qqioSHQt9RXI1WmcGs1pg7bwh4vb+k22mN0Wv32uLYydnerzLbcoi3rRItX+8suwYUM8GDth\nAlRXx4+ZprKyU1JUW3u72q5fr87NyYHmZnVeSYm6ju3PtwkE1DPt2gVf/nJ8RPCd78RjA9/9rtq6\n3UCgruUewWjrX6M5bdCCP1zcIm9nuNhWb3292q5bB36/EuWLL1bn19TABRcoK37SJCXOu3apzwcO\nxK9fVKQEvL1diTiobVeX+uzzQWYmHDyo/hRaa8XbnUQyeXlw773wox+pe11yCRw9qtxK0D2AbLuB\nVq6EZcvinYct7smdnEajOXWRUp4yf+bMmSPPCH7+cylBys99Tm3tP5MmqT8gZXZ24rHkPx5P97aU\nFCnT0gb/PfuP1yvl4sVS5uaqfZ8vfqyiIvHZr7lGbRctip+zaJE6Xl9/En9cjUaTDFApB6CxI2Lh\nCyF+AywBjkopZ1htY4DngVKgCviSlLJpJO53ytHQEJ8UdfvtylresEEFYf/yF2WFG0bcck9Ph4kT\noaUlfg0hlKx6vRCLxa15N+EwBIPdv+Omp+/ZxGJqtGFjGInvYKdkLlqkMoDOP1+5hKZNU0HkJ55Q\nn93fSQ5S64wejeaUZaRcOquAJ4D/crXdC7wupfyZEOJea/9fRuh+Jx+3sNlplTabNyt/e0WFCpru\n3QupqXD99aq9qUl9PxCASER9x+eDaFSJcl+EQjQCedBN7J32oWBn/thceaXqmFasUMHgNWviYm+/\ne0dH/L11Ro9Gc8ozIoIvpfyLEKI0qfk6YIH1+RlgA6eb4PdlrSYHazs61OfOzngQ9qabVLrl3r3K\n515Xp8Qe4MiRxOtFowN6pAeAXwFvAlNd7Z8AlwFfs84ZFCUl6hkvukh1QhdcEPfJr1ypYgu3364y\neNxCX1GRkL3TKg3+8neLWSRNgtqnr9GcchzPtMxCKWWt9fkIUNjTSUKI24QQlUKIyno7W+RUoa80\nS3eqYn6+EkSATZvUdvZs1fbee2p/0aK4hez3D+lxHgBWAIdR4v6J1W6L/WHr+AMDvaDH+uu3O5ut\nW+HPf1bvcNNNKq1z2TJ17NNP4zV93nknMWhrdYbro42szArz8l23aneORnMqMhBH/0D+oHz12137\nzUnHm/q7xikXtN21SwUvd+3q/9yKisTg5qWXxvcvvljKiy6Scty4vgOuffypAEnSn/Eg11rb5GMV\nQ7yP9Pvjn8vKpPzmN6XMy4u/h/3Z3lZUOIHcFjMqfx8+IlvM6HH+i9FoNG4YYND2eFr4dUKIIgBr\ne/Q43uv48NJLyj3z0kvdj+3eDVdcoSxe96SjsjLlIvnzn9V+bq4K1r73Xnc3zgBpRLlx3CxlKZ3k\nsAToJIelLE04/ivre4MmGoWMDPVn7141GayxUaVzSqk+g9qWl6vP1igoS/i4PlBIltDZvhrNqcjx\n/J/5EnAL8DNr+4fjeK/jg51tM39+9wlH9uzY9evVzFZQbpv16+HwYbXv9yuffdPwkpPyUD57222z\nlKXcyZ1cx3WsYAUVVFBKKQBrWMN46/whB3DtyVygsoJCobjQX3opnH226gwuvBCuvloFqd15/DpL\nR6M5JRkRC18I8TvgPWCaEKJaCPFVlNBfIYTYAyyy9k8vbAv/wQeVFeuuSPnII0rgbV/2ihVqElN5\nuQrcpgaVtez1quNFRfGOYQhMRYn4eGADG6iiilJKeZqnKaWUKqrYwAZH7Kf2ebV+cMcYQiE1QQvU\nKGXBAvj1r2HJEtUJPvhg4ijIXpDFXbtfo9GcEoxUls5NvRxaOBLXP2nYmSbz58O+fYlFxaZNg9de\nU8d371ZW7tVXqw4hHIbWJugKxdMsa2t7vscgmAqsBJbQzApW8DTxYPIKVtBMM79lmGIP8WCuXdah\noCA+h+Cdd9Q72r/NtdeqTqCPrJxWabA+2sgif96w3T0jeS2NZrShi6f1hV0q4a23VGqiXXUyuY78\nP/6j6gyuuUb5vPfvh8bmxGvl5g77cT4BbgNyyKGCioRjFVSQQw63Ec/eGTLhsIpFFBWpfcNQKZu5\nucpl1VdxuNtvV9k8VtZSqzR4LHSAVZHDrI8OKaqQwPpo44Cu1SoNXozU0SqNPs/TaEYT2kQaCMn1\nch5+OLGOvB2gbWqCs8+CS2ZCagHs/ERZyRs3wrx58PrrKhd/CLhTL5eywHHjuH34C1jAGtZwGcNw\n69g++2XLVFVNUKOb1lb1uaBAWfV2yupvfqM6w44OSE+n7da/57U7v8wifw5ZDQ0c+NXj7L5pAXML\nJ7HIP+SoAqBEPCRj3Ogf1++17I4B4PpAjxnBGs2oQwv+QEhe9s/tzvjd7+ArX1GWb3ExfOdmOLIe\nPmhVZRVyc1VHsG+fWrlqCILfSFzsQQVmQfnym2nmbu52xB7iefofMoTAbSikSkK8+aYq8AZxsU9L\nUwXhXnpJ/QYbNsRHNgDf/S5VRhurvrWMkDSZ+aunmHn/g9wLTLr3h2QJX4JLBujXPWOff6Evm1+H\na6iMtXJrYHy/7hz7+sPtZDSaMwnt0hkKdgfw0ksqWHvkiKpUuWwZXP1lmHcL5E9W57ozdHbsUNtA\nYFAB3DzUDFo3a1hDGs2sBdJodsTe5msMMUvH71cuqcrKxLjDWWepYLTt1gJVa6eiQgWwASoqmLzs\nBn7yy9WkNDTys5sW8NFDP2Dm1+5wxN7t3unNPeN2x6yN1LMqcpj/CB2iMtbKXG8WF/qyeTZcy7Ph\nw7RKo0f3jU4R1Wi6owV/OFx7LVx9JXxpPvzkR0oIU7Ng4nyImvHslvwc8HvitW9isXi9e8/A/goe\ngASvvZ2Ns5h49o5NBYOYbStE4uerrlKfMzISz/v855XY2+J+yy2qs0tPj3d86elk/M/LzLz/QRb/\nv3X8zfjpTLr3h5Cf74i9W7RbpMF0kU6LGU0Qa7sjuLfzE1pNNQs4LE1meTL4akox7xstPBc9wnPR\nOtZG6hM6kRozxI+6PqXGDDnXG6g/X/v9NWc62vwZDr9/AV55FVKr4fbvJhZTcy860mAFcL0CYlIJ\nvu0rz8xUVTP9/n7r6TxgbZNr6dgpm0OqpWN3Qqmp8OKL8K1vqf2ZM5WYT5sWz6f/939XrqkvfCHu\nylm+XOXkl5erbKayMgCCy5dzfSDfEdEW06Ay1uqItu2eAdhhdHBIhrkrOIks4WORP4/10UaqZZg8\nGWCWJ5NtZhtIeN9oYZE/j3ozwl+NVhrMiHPd6d507u38hBZiEIa7gpNYGznKR7F2dpgdhKTJzSlF\nvf4U2u+vOdPRFn5/dLXC1tVqa39uqlHb88fCsnPhb78AGw+qIObKp2DOWPj2N2HGpPh1Ll8A55bF\n96dNU26dlhbwegZVPO1Dugdkp1rtDwz2/fx+lYHzxhvwy18q8S4oUEss2pPK7FTMsjIVoN26FX7+\nc9pW/ZoXs2JEH/yRan/wwbi7y+okfh8+wqrIYT6Oqclc53gzeN9osUQ6k2W+sUwX6VTGWvlp5z6e\nDSvB/V7qWczyZFDsScFAlXyeLtIJyRi1Zoi/GE3UEuG9mOpMDSS/DdfSQowgghsChayPNvJctI4d\nplXYjsTqoskW/SJ/HrcGxmu/v+aMRVv4/bHrddj4THx/4zOwaz0010DxLLj3+zBzMTQ0wpGdkFUD\nTzwHl54LXz4HNubDmEnwtTvh3x+BzDzoaoat29T1BBCzatgHfRCy3Ak91bq36E2OBixTds19UB1N\nfT288opTvYxpAAAgAElEQVSy2u1yzqAs+LffVhOu1q8n9M/fpmn7B2Q++hgZ5dP5n/BhnovU4f/Z\nfXwBEXf3uDhy9DDL/utZqr98IzcWTgIkF/qyAbjQl82r0UYapCoRvUN2sCPaQaXRykxvBs1mlG2m\n6igK8LPPOv58tM6R7g6rM9hhdjBNpJGBh3ZM3ow0USPDXOPNI0VYk98Q1JghZ5SgLXrNaEMLfn8U\nnQs5xWqbXQTVH0D1NsgshJptSrCnfA4+/C2c0wmvbYPVH6vvLpkNi1KgrhmWXQeHm2H5lVCSBo21\ncKglbnT6PfD8/4FXX4D/70MonQIffqjGYFPzYdcILBKenq7SJ22xtzsVW+ArKlR2zt69ajLZ+vVq\ncXSAz32O9Xd/hZVZYW5rFSx5+GFSbv48ZEPb1DJa1/5BZdNYgnqhL5s/R5tY8Ns/cNEPfkG1P4+H\nbv8bqmWYvWYXX00p5j9C1cpVAxTi5xhRosBe2cVeoyvh0euJj4CSu8EAEAV2y06n7ZVYAyZwRPj5\nt7Ry1kbqeS56hD8bTdTKMNtj7Xw1pZiQNGkxozwbVgHq56Kq3pHdAfQ00UtP/tKcruh/rb3R1Qof\nrYO9f4GWWtjyAiz+AWSPV4Ifsyzx6m3wxx+rc7KL4O8vBPE8zCsCIwy+NFi9RYl9UQ584TL43Qtw\nsCXxfkuugKZDsL8Jll0Oc2dDxSE41gTVcSHDI8CU3fcFiUro8cDSpWpR8xdfVOvi2jX7hVCZQvYE\nq7/7O1UO+Z57VCrpNdfQ/m8/Z//q55m87AYy/udlWL6cS6XBpF8+yZQQ8KMHmffGnwj/6lHC+SY/\n7dzHDtnB5mgLO2QHf4zWUyejZN68kHZibLzxCqplGAFUxlrp6oqxQ3Y4j5uLjzoG5tYC9Q/XgyCC\nJNLDcXvdrzoZZW3kKGGpWmplmAkiRcUPwlDmSWW1ocpy3+gv7ObS6WkUoEcGmtOV0Sv4Xa2wfZ0S\nyZmLVXaNm12vw5bn1efsIpjzJeW3P3ZQtXU2Qlqe2rbUqlFAcw1kjIVFpeqcWBSIwrKparbq+HTY\n+2c4vxCaymBrDTR2QXk+nAc8/CzsOAp8Au+/r8QeoN0l+Hk5UO9K9bTF3xZ7AaRYAeFQSC2l2GwF\njc87D7ZvV88SDsdXssrLU1k3diD2mWd4NSvGqm8t49ZAPtdbcxAyH36Ymfc/CBUV1F69kOJXXmfM\nM7/lyTtvdB7ngFSWeZ20xDs/n1/ecQNlIhVkl/OYe13WOMAuEi36ZJL7M8N6aQ9xcbfPE0ltjWaU\nQ1Jl7RTg485gCc9H6qiMtVLmSeNGfyEgWBIo6Gax95TPr3P8Nacro1fwd70OlZag+4Mwe1n8WFcr\ndLUo8W4/qpTGtvbHTIaMAmivh5A1IcnrB38qzFoKHcfi1xEekAIKM2HaGOXqyUyBK6bA9dPhyjJ4\n7yBcVKK2O45CThCaQyDT4brJsP1T+PRYvP2cbMhOgb1HVLA3ZsaXSgz4IRJVQp+XpwS8vV1VuLzg\nAhWA/eADZdUvW6aCzPbMYZfYk5/PIlcg02H5ckLSZP3//gJzvvEPfPTrlRz78hcBg0L8IJTQj8FH\nGBMBtBGjjFS8uNI/gXA3x0ycSGMzgbychDbZS3vyCr72ggBuPoi1OS6hegx2xDq4KzipR1fNi5G6\nhDY7n99NT20azenA6BX88oVghJQ6lCfVeNu+DrZZE5lSMqC1Vgk8wLH9MHaa2rdyxIlFoX4veLzQ\neCh+HcuNQHsY2sLKkv/MuPjxjBQl9hv2Q8SAa6bC9iNK2HcfgHPT4R8vgLeqQQRBhmD+BHjmQ/X9\ncWnQIeAzk+Av22HxXDhswPubYfYE6ChWLhqAxYtVCmV6erxEhJ11dOPfqnNcJY17FLX8fF6+61ZW\nRQ5za8DPont/yEeRo0y30h6v8eRxlCiHYl0cc0nxAboIyoElhO1+6D84uGo1F61bScaUeJZT+54D\nvLf4NkpuXca0+/9pQNeKE38WH1BvKifQ9YFCR+TdM3ntY260315zJnDm/8vtalXWfPnCRLdNahac\nbxX5PLIb1twHl92h3De1u1R7Wi50Wu4T02VLdh6DgrOhYX9c1AHqdvf8DO8dhPWfqs8fHoErMl3H\nDsHL1veWnQsB668kPaA6h4wU8JmwulIdzwjC35YDBhRlqusGumD6WPhMqnL5vL8ZaIdcL3z5Oph8\nnqpxkxXjoltuouFXj1P6D98gs/o9lXU0j34XHG+VBr+P1PFxtJ3pnnSme9OdiVTTPekARJFEpcnZ\nnlTqzLg/Xjm2km3x7ux+6D/45Kcr1c+y+DZH9G2xD9XWO8cHI/r1xBeGN4B1hgqA18kIE0UKq416\nNhst7DA7mO5JTxjV2EIfkjGei6qyGNq615yunPmC706rLF+oXDMCmLE4fvzjV5UV//qjyhdfsw2y\nxkGre4UqS7D86cq6ty3+AdD4mXHkhQ1AKIvebm+PkHfRRAgbgFTHysbAU+9DeyTeOdjfueRsdV5h\nJnzzIiBbuYgIKuGfegSuugj+OAYiMdX2wBeh4gFei9SxKnKYMb94mgUP/ZLdDY1MyxsH85Z1H+H0\nwPpoI6ujR52f4l+7qqgjyjTSiFnpo2/GjjHUOapusQcI1dbz3uLb+Mzj3+fDO35MqDb+ew9F9JOp\nNFqpI0KbSGOuN4s2Kwh/TMY7Kvfs4Bv943SOvua058wXfFvMyhcmBmIlyne/8RmY/nmo8ai8+h0v\nQ8kcZd0nCL6F2VNOSO88sHYXv3rnAG/edQlTC+PlCj6pa+eyx97ha5dM4oEl5fEvvHcQ2qPKYnd1\nDuqZYyTMlSscB8v/FkJeIASXzYSn/gtqjkGmV40ILp4IwBWGnym7PqJUpgBQ9s7b8P6HqpTx5UkB\n6yTsKpVXeMfwYayNTHzstYKse+h04sZDFftIYzMHV61OaFvKUjbUbmDTF+8khxyuZmlCvaCDq1Yz\n+R9v7ObTHwi5eJ3JXA0ywu5YJ1f4xnDECFMrI6yN1BMUHkIy5pSCmOPL5HnL9aNdOprTleP+L1cI\ncTXwC8AL/F8p5clb+ap8IRz6IJ4/7+4Mzr8Jtr4IhdNU4LV6W8/XiA08dfCBtbtYYblrLnvsHUf0\nbbE/3BJyjjuib4v8RSXKnQOqE7Bz+6+YYl1dxF1I/lSrPQRLp6h00JsugDFeSE+BravJNELMrHwR\nFi2Dzi/jzamGeV8e0MIltjtjrjeLOqKM86Q4Ax4T8AMXiRzels0DcNx0J5CXw0XrVjpum/6WcAwW\nFXDRupVDEnuAZmJOYLfR6qYOGiFaiDHLk0lYmjwXPcIy/1gng+e34Vo1CSwMP0w9u9tvpH37mtMB\nIXuZzTkiFxfCiyrlfgVQDWwGbpJSftzT+XPnzpWVlZUj+xBbV1t+6ltUJo7t0y+9AKo2xX379nkj\nhFvsbcZnB1l58yxue3Ybh1tCCccqrpmWaOm7aQ/Hs3nsTqAnciaqQLRpqNhDRiFM+izs+KOaKFby\nWfWuZZ9LfPdeeNFyAy3zj+WQGeKGQCHvGi18YnRwRIYdsQTIwkury1c+FGxffbA2yqM86og8QBVV\n3M3dhIr83QK6Q8GP4CxS2Y1KDy0XaeySnSzzFfBJrJMdsoNrvPkcRdXqWezLZ1usjTuDJUzzxkdq\n9m90a2C89u1rThpCiC1Syrn9nXe8a+lcAOyVUu6TUkaA54DrjvM9EylfqMS+9AIl6iE1s5M9f7HK\nJLwePy+zl/+wHn/P7b3Q2B7hV+8cSGhbylI6W4Iseep9OluCLGVpwvFfvXOAxvZe3EUZVipnX2IP\nEIuo2IIdaG6vg4N/VZ/b6qDmQ5WKWrVJdX59iD2olMwb/ePYF+ukMtbKjlgHn8Q62CE7uqU+Dlfs\nATKmTOIzj3+fZmsJRzf2Eo6fefz7wxZ7gBKC/CD9bKYLFXCe4Aky15sFCGdC2AHZ5QSlq80Q1TLM\njlhHwnV0/R3N6cTxFvxiwJWnSLXVdnxwFzqzSc1S4la1SQn8u79RW4HqCMoXxq3+ks92v6bwwiSr\n4+ytQ0giLyPAm3ddwvjsIIDjorCt1kd5lDu50xH98dlB3rzrEvIyAkN/95QMJeoAeZMhoISMtjoo\nmq7iE5fdkfjOyb9VD+w1O9lmtjNBpFDqCVJlKos4F7+aTIWy7keC9j0H+PCOH/e5hOOHd/yY9j0H\nernCwBECKjr2st+aAFZrhqmMtbIx1sI13nxu9Bcy1co+8iHYZrYz15ulhV1zWnPSq2UKIW4TQlQK\nISrr6wee+dIjdkaObbW7sS39i7+itjMWxydbvfEL9b3ULJi2UIlnttUvyZjqLHwpcUEdAFMLMxzR\n38AGqqiilFKe5mlnecINbHDE3h3QHRLBbDUBDCCQBhHLEi2eBZd+Ayaep1JObcu+r9/KYn20kcpY\nK5l4qZZh/jNcjW3bh4lxRIYBSEmaVDUU3KmXC1xLOC5nufPbLWCBk70zHNEPoOr1fEoXndb7TPWl\nU0SAWhnmgNlFUHi5MqCs938KTuTWwHi+mlLM+mhjj7X7R2K9Xo3meHO8o0w1wETX/gSrzUFKuRJY\nCcqHP6y7uYOwbpJz8XMtoW+qgVceUiURCs6GD9dCZoFKzXTn1MsYGIN3WUwtzGDlzbNY8tT7rGAF\nTxNf/Nt2Ufz25guHL/YAHY3xgLIRUsFn4YP5t8VHNxDv5Hr7rVws8uexPdbuTEaa7cmiPXaMNkyq\nrQo2GXicQG1y+YPe2pKJNDY7Yg/9L+Foi/6l7z0/pMCt7TizyzLk4eNvLP/76uhRYkKyKnI4oX7+\n9YGg469X++p8XWZBczpxvC38zcAUIcRkIUQAuBF46bjdzXbf9FQXx23N2u6Mt1Yqsc8aB8eqlVXc\nWNX7BKpB8kldO7c9u61PF8Vtz27jk7r24d/MCMc/13+q3uHIDtj5mopflMxRW5tQGxzeHo9pWCTX\niC/zpLHMp7JVLgvkUuJJZRppXOzJIhMv+QSc4G1Pwj6QHjyQl0PJrcsS2tawhlCRnwv++xeEivzd\nlnAsuXXZkLN0bHItV9Q4oWIjfxNQxdPOEmr5ybA0aZWGs5zihb7sbv56vZSi5nTiuAq+lNIAbgf+\nBOwEXpBS7jie9+yR8oUw9waIhiyxf1F1ABn5SggnfhZiYVX7xsar/O/4Uod0S3fqZV8uisMtIS57\n7J0REP0kabXfZe87qmM7uEVZ+jbv/ka1vfubhK+5XRRqAZEjZHt8XOofw4quT9lhdlBDiDTho40Y\nHsubk4V3WMPFaff/E1Pvu83Zt1MvC6+ez0XrVhIsKnCOTb3vtiFPuvKjLPqzRJBGYhQSYIfsYG3k\naDy90qM6gn1mp1NW+bloHb8O1+j0y1OQxi7Jk1sjNHYdv4zDM4Xj/i9XSvky8PLxvk+vJRTs9mhY\n1ccRQON+dayjARZ9G/70f9T+mBJl4QPErLTJ9DHQ4vJCCR/0s+ZpY3vEEXvo30Vhi/6H37tseIFb\nG48XTMsF1VGv/pTMibtvulohd6JK37z4Kwlf7a065GOhA7Rbzpt2TN6PqfLOddbiJSORpWOLeHIt\nnYwpk5w8/aHV0okTRWXkHLWeO9/j5/O+fELSdNw1SwJj2WuqDJ1zvOnc6B/HTsu1tT7aqNMvTzGe\n3xXlxxvV3+c3Zo/A/58zmOOahz9YhpWHn5xvn9xePEtNuJq1FIwIHPorLLwbaj+O+7fTC5Q4AqTn\nqw5hiIxoHn5/eFPUCMWfCoEMmDhLBZ6P7oHaHerdr/h2vCPs7bfqgVZpsDZST6sZZXesk2ai5IsA\n1wYKWBmupoUYRSLAbE8WQsBfjVZqkyrUJ5cw7o+eqmL21Z6M+3493TsXH00YTBAp3BksYYvRRljG\nSBFep0Ry8oQqPcHq1KWxS/L8rig3lPvJSx1+AsHpyEDz8M+cf7m9BSHtfXuilRGKV8Lc8oKycLta\n1PKEbZbAF04DxPAE3xJvW/Td2Thv3pWRMAIYkti7l0D0B5Tg54xXgr9rvRLzq/4lcdTjnnQGA66h\ns65tH4s+3cr4qfP51G/yBf9Y6mWUFmJMEClUyzBXeQNqvVkiZCNoRyJRGTxdA/LkW68FvYr6QMQ+\nHUE6Xo5iEAAmk+ZMrrJpwqBIBPhfvly2GK1OUbQb/YUJou625HVJ5FOXvFShLfsBcuYIvh2w7as9\nd1k877x2l/JhA4wtiwdqg1kw7px4p9AbwmvVtukdW8STa+nYKZs91tIZKO6RmR14rbcqcrrdN27c\nheT6sextLvRlk7bvY67+63payeZqr6T03ElIa7RwoS/bWSN2bUSNjlqQBBGEkI7YB6zVqaDnzB3b\nEh/ueDOAhzYriBwBzvVlEDQ9TPAECZsxtpnt5Hn8nONJ57noEWch9RShlk6x3Tr2mrfaotecSSOI\nM/dfcn9lke2UzINboKBMuXr2b1QF0/wpKsjb1apWuMoap2ap2hUybReKm9RsNVJI4oEl5XxrwVnd\nfPNTCzOG57P3+lXxt6QsG7KK1KgluVzE7GXKsj+8PTFbpx/eN1r4/VnnUuxJYabpY+bm58GbCbOX\nuVITfayPNnKpP9f6liRP+PmPSLXj2bfFPhMvbT34+1V6pJdG65gfEhY8HKhbqIkY+cJHlzQ4SwRJ\nEYJ/Ck5UnVJK4mInh6SabDXbl+nUxg8Kj17g/BQjWXAHK8DDFewzKUZw5gp+f9Zs1SaVklkyJ77E\n4VkXwZuPq6ydcdPUeU018PKP42Jvl03OKFBF1mwr3xcEugs+0Kuo99xu2b/BrPiKWm786RC0ZtXG\nospXH25XbqjOZlXmec9f4IKburu5qjapDm78jPhchH5Y5M+DLJg050IIdapOJmn0YIvj9lg7dwUn\nkSV8vBipIwaMwUcIg3EiSLkng09jnd1cLACZeJjny3Vq1QcQRK1OogB/wiLmPWGnWPrw8M2UiVSZ\nIafo29tGM9XWJDG35e5e9QoS3TY6v/7UwRbc9w7HeOzyYIIA31Du71fM7fM7DUmaTwy6o7iy1Ofc\n63TnzBX8/iYWuY/bI4AtL6hOYPOzMOE8ZQm/8pASUYBx06FwihoBSOKllvEoAfb645OfcktUxxDr\noT5On5k+dq1h13H7/JRMCLdBtEOVeWirg/JFanRhhOJLNtr/lpPdXAOYbJVMgu86NYvW876gRFKm\nOdaye4KWLaAhGWOWJ4NtZrtTWOzFSB0vx5Sgp+PhUm8uUSF512imDZNKo8Wx5O0ZvbM8GfxTcCI/\n6vy0WzAY1Bq1Y0UKU33pVr3+GFVmyLHY7Wybud4sLvRlO/XtQVnuvVnv2md/6nBDuZ/3Dsd4/WDM\nEfdOQ9IZlTy9PcIjlVE6Dan+6whYPiOQIOi2UHdG5aAs9TPJsrc5cwW/N5+++7hdI98WfTtFMXei\nGh0c3m5NzCpSpQlaDivffskcde7uDapAGSZ4fHGxD2SAz58k9gK8VnA1mN6j+ycBw7KCUzKhbL6q\n01++UK2yVbNNjUZSsxMDsqD+0duLuwz2NxkAbleH21r+akoxhJVPX+Xv13GjfxyzfUpo7WUEN0db\n2CE76MBkrDeFkDTpsJw1dUSZSArV1oq3szwZfCd1MlnCxw/TzuaJ0EFCpskxojRhUCZSSRdetpnt\nzCTDKWXsttjdVrxdKkLXxDn16MvtkpcqHMv+ylIfz++KgoRHtkSZX+zhnjl+Zx8gzZcYxLWDuo1d\nkjS/4MpSH09ujTgdgX3dNXuiCR2GfXwolv2p6vc/cwV/IGxfp6xiI6T8+rnFsPgHyo3TdCgunBd/\nRblDdvxRuXQOblGdwtkXwYcvqWUOTUOlP8YMNcO1McnHj4z7/d1i7/HH18ZNJpipfPTBzHjRM+ie\nebN1dbymf1ONqg108VfU+7jpLa4xCNyuDrf4h6RJZayVsmgaSwIFzjm2e8c+7760s6zgrrQCvWoV\nrWkijaDwcJY3jUPRo8z1Zjm1a+zA8H2pZyWkSIasuvVzvVksCYztMbjam5tGB2JPLRy3S1SJcrJQ\n2qL95NYIP94Y4Z65fuYXe3irRhkLP5lvTZQUcYF2u2RerTK4odzPN2YHePDdME9ti9LYJclLFY67\n6PWD8djS8hmBM9LvP7r/1cukrY3t6249oiz88TPiYttWr6xtO8d92kJ1/oTzIHe8muB1ZIcScV9Q\nWfnSBH8aRDuVKyYtR2UFpRco4W2wsmsyC5XlDsptlFy3vqs1vkSjzdYX1aijqwUuvjU+gxZU5+Vm\nCFk6yfQmoLZwg+zmDkn2h9uB0SzhY0lgLEHhdUR9ujfdqb1vLyrurufjHlXY17JHFf0JuXbTnFq4\nrWDH7WLIBH99stgmWN0ywls1Jm/VmHzvrRDnF3lZWubn3zaH+HO1yaUTPKzaEePPhwzeqjFp7DLJ\nS/Ww9ahyl76y3+AXC4MsLPFy55wAHZEQG49IuqJq5u5T26LsbTapaTOZke/lG7MDAxb/4YwOjiej\nW/BnLu4xCEn5QuXOObile4qjz+qtx05RZZPLF8Ls65Wv/9O3YM4NqhBb/aeqRHGnNcFq6qXQeNAq\ny/xlNeHL9rsXTVcuofm3dbfK3cFV9xKNPuu597+v9hus2cO2WyppBq3zXu7tMEieiGQLd3+ukp4C\nvLZ/f1XkMHO9WUrcIzjulxsChRCJu4vc2TPu79ptmtODZCvYdrtsPqKs7Se3RshLFQkWujvnfvnM\nAMdCktV7DEf436022HhEWXDRmMnCEi8FaQIweXq7QSgG84o8TM6C/a2Sr7/WRU07NHSFSPWphIlV\n2w1KrAHwmk8MQia8VWP2mu/fk/vmVJ0bMLoFv6/c/cvvTHR/2CmOc2+Iu1dst8gbv1AjgZxi1YkI\nlOBPvlC150+Gc66IV+bc8oK6/tYXlRvILfR9uV3KF6p6QPbyjLteVwHlnGJ1DYi7pQbzvkMgWXj7\nsp6T/f7JAV7bbQNK1GcYGc7W7Xu327cabRyNhXk2XMuSQEGPGTV6Zuypj9sKdrtfojEl2JuORNlS\nB+uromw8IvmfvRGawnB5iY/rp/p56L0Q2xsl7S6P6M5j8eF6uk/y+sEY6dZffyim1lndWGtyzxw/\n7x6OsbFWuYS21UtA4hHQFYMDVkgsZEJOAM7OFU62DiSKfG/um1PRj6//J/RGXxkuyUJsW9NzvqRE\nuOxzcQscVNuev8Q7hYu/otrsyV1Vm+KWfF9ul9QslW45kGc6zgwmbTHZd54cSE22zq8PBBO2yXGD\nbWYb2wBiyqXTU7aNzqM/degrj/6Gcj9Pbo3wyv4o+1vhuV1R9jbboq0s7qi1u82a+L5qh8FrVQY1\nHd3v1RKJT+yrtuoRdrgS3mJAmhf+c1sU0+XK9QkYE4SjXZDqhUcuS2FPk+l0ClvqJGv2RJ2g74p3\nw47P3+64koPBd70RSjjnVBB/LfgDpS/r2Laqkyc6QWItn7k3qEBwahYEFyqXjiTRxTIYt8sIWuyD\nZTD+8L7KFAyk40g+PyRNp/ZNb9/TefQnH1vYOw3JI5XKDP/G7ECCRQzw1DZ1zOeBvc0SnwBDKuG+\nZ66fY12SLXUGBUFoCUNEKmu9N2wd7+gl87mzh+8aUok9wHVTfNS0SxaU+Fi9Rz3bvHGCdw8bbKyV\nTkxgcragsct03ssOKNu8fjDGwhJvn6OAE82ZUzztVKAnd0xXq3L5HNwyoGJlmr7RrprTByejZo7f\nsYxfrTK4stTH73ZG2N5o8p3zU/jjPoPndkVpSk5sA26c5uGP+01aelnu+XiQ4oGwCZOzBftbJDkp\nkOWHg9aIYV6Rhy7DZJs1F3NhiZfHLlejUduKd38eyOzg4bp/Rl/xtFMBt8XtFn93PEAzLLSr5vQh\nOVPF7eL4pEnyVrVJbXuI31ydSlMoxpq9JqEYZAcgxassbrttsJjtjXgyuo/uemt3E7ZqeJyXD80h\naApDcxiCHuXL31hrkmkl3wS9OBPC7MCzjf15IGJ+okYAWvCPF8m++OFY9iOQP3+moF01pw/uTJV/\n3aR83vOLPdxQ7ufKUh/7mjvZ2yy55eVO9ltB0oAHynJhi7V89FDEvm3tQ3S+s4q8u9bhK5zitBt1\ne2h8bDFpl9xK5pL7+73OH6tkwv1DJhxut9Z0ttxFS8u8lOV6E9IvkwV+IGJ+otI4h7XilRDii0KI\nHUIIUwgxN+nYfUKIvUKI3UKIq4b3mKch9qLpI2HVD2DB8dGCXlLw1KWvlae6LIGcke8lL1VQluth\n2VQlbvtdJaMiphL7wBDjmm1rH6L95Z9ittTS+NhijLo9QFzszZZa2l/+KW1rH+r3WsmdjQf4h5k+\nfELFEXICkBsUXFDk5a43QuxtMmnsknzjtS5+vDHCk1vDPLk1wpWlPu6Zo8pBNHbJHn8nu3M83gHd\n4f6v2Q5cD/ynu1EIcS5q/drpwHhgvRBiqpT91BM+kxjJgOoI5s9rNMeLvoqapTpKI3nw3RBbj5qU\nj/Ewr0iwsTaxg0jxoJbOHKRa2GJvY4t+9s2P0/LsHZgttc4x+7yBWPrO9YBf/NXAsB63OQJPbTN4\nZX+M/a2SPcc6QQgOtqkTtjeavFWtero0v5rRm+ZTgn6yArjDEnwp5U4AIbr1StcBz0kpw8B+IcRe\n4ALgveHcb9RyErNxNJqB4k5PdPvrvzE7wPKZAdL8IiFjZ2OtybwiwfQ82NEYv07YxKp9OnDM9kY6\n31mV0LaUpWxo2UDTU18khxwWsNRZVhSg851VpC/4x359+gGPGnlAfOsu3312Dhxut4O6SuznFQlm\n5Hk4f1yiuyf584nO1T9ei5gXA4dc+9VWm0ajOUOx3RKvVhkJKYk2nYYqW3DjNA/ZlmG7sVbSnLja\nJ0Mw7vFk5JF31zo82UWAEvs7uZNHeZRSSnmUR7mTO1nKUnV+dpE6vx+xh7jIu4micvcB3q6WTqAX\nVArnxeN9PLXNcCz6p7erOkGQ6L6xR0XP7+q7/PdI0a+FL4RYD4zr4dD3pJR/GO4DCCFuA24DKCkp\nGdhi3LsAABwpSURBVO7lNBrNScYdgLSt1ud3RR3LfmGJNyHNMnkC1VATxX2FU8i7ax2Njy1mQ8sG\nruM6SinlaZ4GoIoqNrDBEXt3QHew5KSozB1QwdwUr2r7/GQv3z5fpWjaReDc7+5uH25FzqHQr+BL\nKRcN4bo1wETX/gSrrafrrwRWgsrDH8K9NBrNKURPdWTsGvZdlpU7NdfPptooW45CVgBaRyjP3lc4\nheybH6fpqS+yghWO2AOsYAXNNJN786+GJfZnZUFdJ2T4oT0KmX5oi4LfI/jKzBTHRWPXBmrsMplX\n5GH2WA+IRP/9ia65c7xcOi8BNwohUoQQk4EpwKbjdC+NRnMS6Ss7xz7+/K6oVWfew1PbDPJSBZdO\nVFZtawRKMtVIIGOYhq5Rt4eWZ+8ghxwqqEg4VkEFOeTQ8uwdTvbOUNjXqmbxtkdVZ5Vu6XV1u+Qr\nr3QluGie3xXlqW0GG2tNUv0CpJo9fLKqaA4raCuEWAb8EigA1gkhPpBSXiWl3CGEeAH4GDCAb46q\nDB2N5gxmMHnmjV2yW00Ze9sUUpUxz87xkOqDTbUGW45Cuhc6hqAW7tTLBSyllFKqqGIFK6igglJK\nWcAC1rSsofGxxcN264DqrKbkCrxIYqjSEPZcA/s9O6PSKfDzyJYo3593/NMve2O4WTqrgdW9HPsJ\n8JPhXF+j0Zx6JAt8X37o53dFewzgAqzZG1ULmAh4q9pUqZgMTezN9kZH7AEnG2cDG2immbu5W4m9\n1W6nbBZ8770BBW6T8aICyx5gS52kLEc4Rd/OL/ImlEn+5wtSAJwVt05mjfzj5dLRaDRnKDeU+/n+\nvLjQ9zVp6MpSH/OLPUzNtbJVPlL1dZ7+KOL484vTVcaLOYwInicjj7RLbk1oW8MaWrNTyf36f9Oa\nnZqQkgmQdsmtQxL7CRlwbZlKHDWBkkxl2WcF4NbpPpbPCPQ5uQro0wV2PNGCr9FoBkVfAm8L3d4m\nkye3RlizR1nxT20zuOuNkDPjtsuQbD2qchmrWnEmM31uvMp4GQqZS+4n45r7nH07Gyc48+qElE2A\njGvuG9SkKzf/q9jD5GwPt05XnVluUP0OrRH48yE1PElOt3R3APaxu94InXDR1/PTNRrNiGGLmb1G\n7D1z/Xx9lp9X9ivXTiQmuWeuGhnYi48cbjeZVQDb6mF8ppdgY4zwECN+togn19Jxp2wOtJZOb7xS\nZdIcVqtpvVVjMmds/Nj+VsnT2yMsn6EseXflTPcsZPv3sYuunSi04Gs0mhHDnX45q8DvLAa+vxXy\ngmqpwEsn+hwhXP1JNKGWzls1MVrC8UVMhkLmkvt7nEHrK5wyaJ99WTYcaiNhYlVzGOZP8HDnnAAQ\nYWKmYMtRg+J0NaegKyq7pVsmz0147PJgQinlE4V26Wg0mhEjL1WQ5hNqlqlfOJOLFpZ4aQzhBG/z\nUgX/fH4Kv1iYSlmO4OLxyo8zLl25R+zaO2me/q1SL+BP8i71JuqD9dnvbYGA6wHsom7nF3rZVKus\n9DFBwffnBbjCWQKxu6vL/h2e3xWlsUuesGJpyWgLX6PRjCjJWTvJFq1b5DbVxtjbLLn2bA/3zPFw\nLCTZ12zQFIayHMEVk7w8tU05/u2VsLwCYi7zP4baLwhCfVKZht7IDypL3ehhGJE8umiL4NS/b4uq\n0gkInDVu7Xf6101q6m1qL6p6Kqx6pQVfo9GMKD3NHnW3Ja9pC/Hqmo9sUUHOyVmCRy4L8vDm+DJY\ntjjbYp+XoiY/hU0oSocOVzkar1AdRLiHOjigvtdT5wGw9GwPk3O9ThbR9gZTpY9a+H2CRyqjpPkS\n39MuENebm+ZEl1HoCS34Go3mhJJs6dqieUO531kvdtkUH5tqY7xVbTJ/godoTAV55xZ6qO0wqWmH\nKWM8TuC31qrHkxOAdL/ypdtCbpduEKhOICcI9db6tWU5sLsp8fkm53j55/NTnH2VYRNm61GT2WM9\n3HSOKhCXLNz9lUk40WUUekL78DUazQklOY/fJi9V8OQVqXx/XoClU9QM1Xvm+nlyUSq/ukq1f26C\nl5p2FQv4+aVB5hXF3UOTswRf+Yyfmg712SbTr0o3SCAq42I/v9jD5SXK5v3/2zvX4Kqu647/lp4g\nBRCRMDZgWcICHMDp4Mq4jhMjGgUoMa8kzbjOTAnJhLo1iWeSmjFlEsFQpg5MnA/BaYdMTZkJtusP\nNbZTHGOlPBKCH4rxAxKwZQQy2NiSggBzQQ/Y/bDO0Tm6ulePeyWurrR+M5p7zt7nnrO3EP+9ztpr\nrz0xH8rHC9+coed+WKnvby8cqYNL4cggDDMdMQvfMIxrSneWrl/380OtXdIQ+MnIwtkmPzcxi5c/\nbKN0tLB94UjGjtBJ43klWex8t41natupO+cAx+hsOO+5fUpHCxu/MIKxI1TM/Tz9Y3Id/3WknTcb\nrnbK5z+vJIuDH1xhXknWoPDFJ4oJvmEYg454/u7owWLFzBzysqTTZLBf/8+zc1k6Jbtjz9zzbWrV\n+6kcdp9o73ApNV1yHQPFX1zX1hFW6j/fz/F/54T2QeGLTxRz6RiGkRK6y7LZm7DFnnaLarrk2H2i\nne0L8/j+X2are+hLI9n4+RF8sTiT2TdkdnLb/NOsHMrGZnQJK2265DrcS/6zotvWU8bQwYJZ+IZh\npIRkXSPR348eALYdbuXRmjaaLqnvPZzdU901rZ3cNj7RFrwfPdRdlst0cfOY4BuGkRKSdY3EEuZO\nousZ2xpW2d5RHt57N+yi8elulexA9eVaIc4NnleQ8vJyV1NTk+pmGIaRRviW/bySrI5wSd8VE6s8\n+nvXagPxgURE/uCcK+/pOrPwDcNIa+K5U8KWetnYrm6WdHHD9Ccm+IZhpDWJulPSxQ3TnyQVpSMi\nm0XkqIi8JSLPiEhBqG6NiNSKyDERmZ98Uw3DMLqSaCKyVCUwSyXJhmW+BMx0zn0WeAdYAyAi04F7\ngRnAAuDnIpLgtgaGYRhGf5CU4DvndjvnvD1seBmY5B0vAZ5yzrU45+qAWmB2Ms8yDMMwkqM/F159\nC3jBO54IvB+qO+WVdUFEVopIjYjUNDQ09GNzDMMwjDA9TtqKSDVwfYyqtc65Z71r1gLtwI6+NsA5\ntxXYChqW2dfvG4ZhGL2jR8F3zlV2Vy8i3wTuAb7ogqD+08CNocsmeWWGYRhGikg2SmcBsBpY7JyL\nhKqeA+4VkVwRKQWmAK8m8yzDMAwjOZKNw98C5AIviQjAy865+51zR0TkaeCPqKvnAedcgvvQG4Zh\nGP1BUoLvnCvrpm4jsDGZ+xtGmEgjHNoGs1ZAXlGqW2MY6YettDXShkPboHo1tHrb2Qkwe1X/i78N\nLMZQxQTfSBtmrdDPtouwb70eZ+fDXQ/Fvj5R4fYHFoh/b8NIR0zwjbQhr0gFONKomW/bImrtRxo7\nC7ov9K0XYb83MISFu6eBYNpiOL4bLjZ0vbdhpDO245UxqIg0woHN+hmPvCKYuw7yx6mgP7O88/W+\nhS7A3VX6RhBpDO79yhatP7Qt9v2PPQfHq+Hg5vjXGEY6Yha+MWAk4lLpjTvFv++0xXBiL9TuUhHP\nyddn+eUz/07Fu3q1un5Aj+dUQeWmwEUUzawVat2fOaT3Moyhggm+MWAk4gv3RTgsxuGBA9Sir90F\n7+2G62fBhNvh/PvwxuPQeBQ+OaP1JRWB+E9bDHmFwb1juYD88rwifXuoq9YBo8j8+MYQwQTfGDB8\ngZ62WF0p8Sz9aEGPLg9P0jafVDHPHKGCXFcNkyuh8R2tf/sJuHIZSiv1fq9u0esn3g4V64KBJ9II\nBzbBh4dgTLEOFhcbYN6mzm2P9xZgGOmICb4xYPiTrAc2q6V/Yi8s295V9F/Zor74SAN8fEQFGlSA\nD26G629XUZ+2GJ68R+uuXIYRY+HyWfW333A7nK/XcoD86+C/vwbNdXoeTtIUaQzeEgByvV0cPjrU\nte3+9RamaQwFbNLWGHBmrYCyhSqw4UnQxmOw48twyZtw/dMzek3ZQv3OGU+Az7ymon74Saj4V/B3\nVhhzExRM1uPSCiieE9z76LNQv08HgRFjVbT3rNNn+mKfmavXZmbD2DKo2NC17f7g0N0kr2GkC2bh\nG/1KpFEtdgFuXgD7N8DdP1SXyoTbA/fOtMXw1FJoOqrul9JKdc+MKYVxM6CpFq60Qc5oaD2v9z74\nU3W/+Ek6PnpDP0dNgkiTirvP1Va99ly9vgXUPKblx3fDqYNq1bc0e21u0J+9P9Q5gaw8uNWb8G29\nqINDaWUQ7ZNXZFa/kZ5IkOAy9ZSXl7uamppUN8NIAt99A1B4iwq6/1m2EK6bAb/fDAWl6m4ZUwxj\nSmD8rfDaY8F9MrLhapta4Vdauj5HssG1xW/HiEK4ZYn65juRhWZ38sgdAy3nAveQT/EcfUMomAxT\n/gaajulbxpwqjfjx5xUqN9niLCP1iMgfnHPlPV1nLh2jX5m1Aj73kFrE83+qIr9km/rga3dB/e/0\nOt+3npED9fvh3V2QMcK7iajYQ2yxh+7FHuByE7y5PUZFe+fT0V4S78tnVeTHFHvtO+F9Hoejz6vY\n5xZA7W4vvUNE+9R8Evau637dgGEMFkzwjX4lr0hdInXVcPAnMP9RqP8tjJ/lXRDaL3pkIXxuNWSN\n1AHgqjfhiut8XU9EaIpZfvFK7PIwDYf1s7QSJs5WFxDA+ZP6FgLBf5KWZjh9UAexnDwdBGoeU0vf\n/PtGOmA+fCMh4vmwI41wco8e11UHfvryB3RitL1V60YWwqUm+M1qaL8U4wG99DTuYR2v8wuWs4ci\npnaUN/IO25nLbXyHuazr9h6SAfUH4NTLQVluAUxZCCOLoGwBvPgD+OQUTFmkq3x9WiMq/vHCN83X\nbwwmzMI3+ky8yBW//OR+Pf90WeDDbzgMZ2vhTI2eL/ulDgCXmxNvxx7WsY/1XOADtjOXRjQY3xf7\nC3zAPtazpwfBd1fhyiVo+yQoa2nWOYX2iE483zBLrX9ftA9t00yd8zZpfL8/kRudFsJffGZvAMZg\nwCx8o88c2qb++MJbgtQD4dj20koovktTG7z4fS2bukiN9rN1Ogj87t90AEgUX+x9fNFfxFaeZyUX\n+KCjzr+uJ0s/msxcXch14TSMmqhlbZHYK4jD/W+9GKR5sAVcxmAi2S0ON4jIWyLyhojsFpEJobo1\nIlIrIsdEZH7yTTVSjW/BTlusfuymoxq6CMEgMLlSQxtBUxks266RLLd9W+PdL3g+8o/fTqIdNPE6\nv+hUtpSlZBLhCe4hkwhLWdqp/nV+EdfXH48rLSr2oG8BoFMLs1Zon/wQ03Bsf9lCvca36v0FXObO\nMQYDyVr4m51zPwQQke8BPwLuF5HpwL3ADGACUC0iU22bw/Qj7IMOW7bLtndOh+B/hlMS+7nq73pI\nFz3VVWt5boEXApkBXO17m/IoZDl7Otw2S1nKgzzIEpawnvVUUUUJJQDsZCejmMBy9pBHYYK/BWi5\nEBz76wzeflL7eujxIOx02fag7z2llDCMa02yWxyeD53mE0y1LQGecs61AHUiUgvMBg4m8zzj2hMW\n+bC4h1MPQOdc9W0RTVMwbbFavy9+XyNxAPLHaww7kJDY+xQxtUP097KXJSyhhBK2oc7yE5xgL3s7\nxD48odtrMtC/aKf+/cJbNALJH9DufCiI1590py4sC/8uwmsSLFbfGAwk7cMXkY3A3wPngLle8UQg\nFPPAKa/MSDO6E/kw4ZTFDUc0ZPHYc7qy9Xg1ZHh/aRc/ivFloddROWGKmMoitvIE97Ce9R1iD7Ce\n9TTTzH38MjGxh04DUtZIXVcwthTe3hHMP/irey+c0YEgJ7QDl/nvjcFGjz58EakWkcMxfpYAOOfW\nOuduBHYAq/raABFZKSI1IlLT0NDQ9x4YA0pvfdD+m4A/SVt4CxR/QcMWAa6262rWrPwYX05wsXcj\n7/A8KymggCqqOtVVUUUBBTzPyo7onUTJyNHQ0YM/0UHsbK1GGL3/u2ABWelfd82xb/57Y7DRo+A7\n5yqdczNj/DwbdekO4Kve8WngxlDdJK8s1v23OufKnXPl48aNS6QPxiDAn8ic/2gwobt/A5z6vdYX\nlMKt90H7xe7v01vCoZcVVFBCCSc4wQpWcIITlFBCBRVdQjb7Skau5uUBTdbWehFumqOifyrkoDx3\n0nz1xuAnqVw6IjLFOfeud/xdYI5z7msiMgN4AvXbTwB+A0zpadLWcukMDfwEam0RXdB02hP90Tfp\nCtak708T/85nO4VeLmUpe9lLM80UUEAFFexkZ0f9KCbwj7yV1MRt8d2aBmJsmQr+TXfDdbfCuy9o\nCoY5VRqTD7bgyri2XKtcOo947p23gHnAgwDOuSPA08AfgV8DD1iEztAi3t6zHZuWRDSXfWa2lo8t\nC8Q+IxskJ/Fn51HIbXynU9lOdnKFPO7jV1whr5PYA9zGd7qKfWbs++eOjl3+6SmB2BeUwoQ7VMyb\nj2u9774CW3BlDE6SEnzn3Fc9985nnXOLnHOnQ3UbnXM3O+emOedeSL6pxmAinqD55adf0fPxM9XV\nc9+vgtz1V9vAeW6S3DGJPX8u65gT8tv70ThT+TLL2cMoOpaEMIeq2Iuu4pggo2+E7E91LT/6P8Fk\nbXOdDmitEV1RDJpiwcd3cUVv1djTBu2GMZDYSlsjIeJFoPjn506q+yMrL4ha+cYueP4f4Mzr0OrF\ntbecS7wNvohH59IJh2z2JpdONA1HYpdfPgujijVSZ/xMzbMjwJ9rdd5idihkIVZEUyJ7/BpGf2KC\nbyREvBBNv3zPuqCsY/FRoYYttl4AyQLnpypOMCwTVPTv4Ltd3DVFTO3RZ585ItgSsbeMLdW4+6lf\nDtYdZOf3zldvYZpGqjHBNwaEOzxr99QBjcP3qd0VbG7SgVPXTusnwW5WfSGeqPc0QeuiF35lA1F5\n9gsmq4unfp9G50yYDSUVgWh3tzahS3v6cK1hDASWLdMYEPI8d8fxas2v4ycSKyhVsc/IhaKZwQbi\nLecCsc+OitXPyA6OJZ6J0se/ZMnStw2f7Hw6xD78/OlfhcpHdF3BqInqt2+LBNZ8on558+cbqcAE\n3+g3okXM99JMuksFMq8IRns7Sl1tgcbD8FcPaoqCMaXBfYo+o58FZZqrPvw2kD9O97CN5lPXx29X\n5ojgOHuULqRy7cGWhpKh6R781cB+6oeCUpj1bV1P0HQU3ntRy/3N1SHxaByL4jFSgbl0jD4TL8Y8\nelLyjlVBmmD/O5WPQPXD3sYhIzWFctE0+MxX4ImFKsIT74AZX4cDPw7cLv4euJ98GAh4/kR9i/jk\ndAz3TIgrl3VAKZmrE8nRaZkzR+qCsKvteu+RhXrP5jpNkDZuBlxphTt/AK/+TBeX+UT75Xsbf2/+\nfCMVmIVv9Jl41ml0KGLYZ+1vmPKbhzXl8JnXVHz99Mr7NwQWd773vWW/1HQMN9wOX3kCJt6p9f5E\na/tFFWaAi2f0c0yxXjdupp77qRymLtTUzGdr1TVTUBpcc8vSIGT0ymW95+hiXVjVsZ4gRydsSyp0\n8tknOn1Cby13S7tgpAKz8I0+E886jTcpGd4w5eQ+LRtbBrd+I7D+r5uhrpQJs4PwxikL4PNrVEDf\n+zXkRvn2W5o17LPdW/A0uhjGlMCirfDCKt1ly0/lUPsi3Dxf5xTaIjro3F2lPvr6A7p46qa7dfPy\nc/WaFO18vbp/Sr0N2CH4jDf5apa7MZgxwTf6TF+jTXzxm7YYDv0nfHgIFm5RV054p6jKTV3vG86z\nf7xaI2Wc01Wv507C9K/D/62BMZP1reF8PexapZuwtLfqoqi6PWrZZy/TQcffdvGOVToY1VUHuexf\n2aJZL4vn6CrhumpNmXDzPG1/OEKnP343hnEtMcE3BpywCH5pU+c63/ovWxhbSMN59nPy9S1g33rI\n+RR87UkdLC41qcDf+ZBOqF4/S90wc6o04iZrJNQ8ppb91EVwZhLM3RCkc4bA5x6ed/DbF/bHF5mY\nG2mMCb6RUqLz7ceb9AwL/+nXdJA4tE0nUK+2wvhZ8PnVwT3yx+lbQfVqfSsA+PiwxtNXboL638Ze\n9RptoZu1bgwlTPCNlBItsD2lH8gr6ry9Yl4RTJ6n38kfF0yEht8KIg06dzBxtq6QDb9JmK/dGE6Y\n4BuDirDF35O1H+s7YcLCnzeu633MejeGGxaWaQwqwuGKiYY4Ri8AsxBIw1DMwjcGLYmGOFpWSsOI\njQm+MWhJNMTRYuENIzb94tIRkR+IiBORolDZGhGpFZFjIjK/P55jGL3BXDiGEZukLXwRuRHd3rA+\nVDYduBeYge5pWy0iU22bQ8MwjNTRHxb+T4HVdN7CYgnwlHOuxTlXB9SiG5obhmEYKSIpwReRJcBp\n59ybUVUTgfdD56e8MsMwDCNF9OjSEZFqIFa28bXAv6DunIQRkZXASoDi4uJkbmUYhmF0Q4+C75yr\njFUuIrcCpcCbIgIwCXhdRGYDp4EbQ5dP8spi3X8rsBWgvLw8wZ1NDcMwjJ5I2KXjnHvbOXedc67E\nOVeCum1uc86dAZ4D7hWRXBEpBaYAr/ZLiw3DMIyEGJA4fOfcERF5Gvgj0A48YBE6hmEYqUWcGzxe\nFBFpAE4O8GOKgKG6dfRQ7Zv1K72wfl17bnLOjevpokEl+NcCEalxzpWnuh0DwVDtm/UrvbB+DV4s\neZphGMYwwQTfMAxjmDAcBX9rqhswgAzVvlm/0gvr1yBl2PnwDcMwhivD0cI3DMMYlgw7wR9qqZxF\nZIOIvCUib4jIbhGZEKpL535tFpGjXt+eEZGCUF3a9gtARP5WRI6IyFURKY+qS/e+LfDaXisiD6e6\nPYkiIo+LyMcicjhU9mkReUlE3vU+x6ayjQnhnBs2P2i6hxfRWP8ir2w68CaQi6aKeA/ITHVb+9Cn\n0aHj7wH/MUT6NQ/I8o5/DPx4KPTL68NngGnAXqA8VJ7WfQMyvTZPBnK8vkxPdbsS7MvdwG3A4VDZ\nJuBh7/hh/28ynX6Gm4U/5FI5O+fOh07zCfqW7v3a7Zxr905fRvMxQZr3C8A59yfn3LEYVenet9lA\nrXPuuHOuFXgK7VPa4ZzbD/w5qngJsN073g4svaaN6geGjeAP5VTOIrJRRN4HvgH8yCtO+36F+Bbw\ngnc8lPoVTbr3Ld3b3xPjnXMfesdngPGpbEwiDKk9bQc6lXOq6K5fzrlnnXNrgbUisgZYBVRd0wYm\nSE/98q5Zi+Zj2nEt25Ysvembkb4455yIpF2I45ASfDfAqZxTRbx+xWAHsAsV/LTvl4h8E7gH+KLz\nHKekQb+gT/9mYdKib92Q7u3viY9E5Abn3IcicgPwcaob1FeGhUvHDeFUziIyJXS6BDjqHad7vxag\n8y2LnXORUFVa96sH0r1vrwFTRKRURHLQfa2fS3Gb+pPngOXe8XIg7d7UhpSFnwgu/VM5PyIi04Cr\naPTR/TAk+rUFjVZ5yXsre9k5d/8Q6Bcisgz4GTAO+F8RecM5Nz/d++acaxeRVWgkXCbwuHPuSIqb\nlRAi8iRQARSJyCn0rfkR4GkR+Tb6f+3rqWthYthKW8MwjGHCsHDpGIZhGCb4hmEYwwYTfMMwjGGC\nCb5hGMYwwQTfMAxjmGCCbxiGMUwwwTcMwxgmmOAbhmEME/4f9idttHCSXWkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1c209e21d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids, data, n_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def index_b(a,idxs):\n",
    "    ir, ic = idxs.size()\n",
    "    ar, ac = a.size()\n",
    "    return a[idxs.view(ir*ic)].view(ir,ic,ac)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "a = FT([[1,2],[3.,4],[5,6]])\n",
    "b = torch.LongTensor([[0,1], [1,2]])\n",
    "exp = FT([[[1,2], [3,4.]], [[3,4], [5,6]]])\n",
    "assert(torch.equal(index_b(a,b), exp))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def dist_b_n(a,b,pts):\n",
    "    dists = sub(pts,b.unsqueeze(1))**2\n",
    "    return torch.sqrt(dists.sum(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def meanshift(data, bs=512):\n",
    "    n = len(data)\n",
    "    X = torch.FloatTensor(np.copy(data)).cuda()\n",
    "    for it in range(5):\n",
    "        d = X.cpu().numpy()\n",
    "        nn = BallTree(d)\n",
    "        for i in range(0,n,bs):\n",
    "            s = slice(i,min(n,i+bs))\n",
    "            nearest = torch.LongTensor(nn.query(d[s], 50, False)).cuda()\n",
    "            pts = index_b(X, nearest)\n",
    "            weight = gaussian(dist_b_n(X, X[s], pts), 2)\n",
    "            num = sum_sqz(mul(weight, pts), 1)\n",
    "            X[s] = div(num, sum_sqz(weight, 1))\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 1.45 s, sys: 16 ms, total: 1.46 s\n",
      "Wall time: 1.35 s\n"
     ]
    }
   ],
   "source": [
    "%time data = meanshift(data).cpu().numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n38idZEYyccAl3kDf1bSNzYfWedfrg1FUZ/ToKB1jTIsx5nTgBOBsETmlzXqD1eoPdqBzRaRYRIor\nKoL/H0Wp3nJy9PkBZR81bnCP5Hmcfc07vOXxYUM4J3Zqu9v68FCRLewBKtjpnj7BV8dfZx6uolRn\ndekoHWNMlYgUAlOAfSIy3BizR0SGA/vb+U4BUABWC78rj0epUMWHDSE7fh6Npp63a19u06feyuaG\n9QyNOJFdzVtt3/t61LneCdn2Ne9gc8M/GB99YUALH+w3WU2IzrS18JXqSiG38EUkWUQ8XTexwKXA\nVmA1MNNdbSbwcqj7Uqq3REksFwyYxgCG+JWGMTQ8NSDshTBbiA+NGM1l8bPZfGhdQNhHEG3rnz8h\ncqx246hu0xUt/OHASnc/fhjwgjFmjYi8C7wgItcBO4Dvd8G+lOo1URJLVvx0W1mjqYdDYgv906I7\nnpDt+PBRh524TUNfdYeuGKXzIRAwmbgxxgVcEur2lTqWRUksp8dkcTpZR/S9UGbpVOpo6Z22SvUQ\nbbWr3qZz6SillENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo4Cul\nlENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo4CullENo\n4CullEOEHPgiMlJECkXkExH5WETmu8uPE5HXRWSb+31I6IerlFLqaHVFC78Z+Lkx5mTgXOBGETkZ\nuB1Yb4wZC6x3LyullOolIQe+MWaPMeZf7s9fAZ8CI4BpwEp3tZVATqj7UkopdfS6tA9fRFKBicA/\ngaHGmD3uVXuBoe18Z66IFItIcUVFRVcejlJKKT9dFvgiEg/8DbjZGFPtv84YYwAT7HvGmAJjTIYx\nJiM5ObmrDkcppVQbXRL4IhKJFfZPG2NedBfvE5Hh7vXDgf1dsS+llFJHpytG6QjwBPCpMeYBv1Wr\ngZnuzzOBl0Pdl1JKqaMX0QXbuAD4IfBvEdnsLrsTuB94QUSuA3YA3++CfSmllDpKIQe+MeYtQNpZ\nfUmo21dKKdU19E5bpZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRy\nCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA18pZRyCA38nrJxI4j4\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1c20920400>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kmeans.plot_data(centroids+1, data, n_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
